我正在尝试在 Go 中像这样解码 XML:
<property>
<code value="abc"/>
<valueBoolean value="true"/>
</property>
或者这个
<property>
<code value="abc"/>
<valueString value="apple"/>
</property>
或者这个
<property>
<code value="abc"/>
<valueDecimal value="3.14159"/>
</property>
等等,变成这样:
type Property struct {
Code string `xml:"code>value,attr"`
Value interface{}
}
标记(valueBoolean、valueString 等)告诉我值属性的类型是什么。我试图解析的 XML 是 an international standard 的一部分,所以我无法控制它的定义。实现解析这些东西并不难,比如:
var value string
for a := range se.Attr {
if a.Name.Local == "value" {
value = a.Value
} else {
// Invalid attribute
}
}
switch se.Name.Local {
case "code":
case "valueBoolean":
property.Value = value == "true"
case "valueString":
property.Value = value
case "valueInteger":
property.Value, err = strconv.ParseInteger(value)
case "valueDecimal":
property.Value, err = strconv.ParseFloat(value)
...
}
但我不知道如何告诉 XML 包找到它,这些东西隐藏在其他 XML 中,我真的宁愿使用 xml.Unmarshal 来处理。或者,我可以将类型重新定义为:
type Property struct {
Code string `xml:"code>value,attr"`
ValueBoolean bool `xml:"valueBoolean>value,attr"`
ValueString string `xml:"valueString>value,attr"`
ValueInteger int `xml:"valueInteger>value,attr"`
ValueDecimal float `xml:"valueDecimal>value,attr"`
}
但这非常低效,特别是考虑到我将拥有这些东西的大量实例,这让我无法在不添加另一个属性来指示类型的情况下派生类型。
我能否以某种方式将它与普通的 XML 解码方法联系起来,只是手动处理棘手的部分,还是我需要从头开始为这种类型编写整个解码程序?
最佳答案
感谢 OneOfOne 的指针,这里有一个与标准 XML 解码器一起工作的实现:
package main
import (
"encoding/xml"
"fmt"
"strconv"
"strings"
)
type Property struct {
Code string `xml:"code"`
Value interface{}
}
const xmldata = `<properties>
<property>
<code value="a"/>
<valueBoolean value="true"/>
</property>
<property>
<code value="b"/>
<valueString value="apple"/>
</property>
<property>
<code value="c"/>
<valueDecimal value="3.14159"/>
</property>
</properties>
`
func (p *Property) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if start.Name.Local != "property" {
return fmt.Errorf("Invalid start tag for Property")
}
for {
tok, err := d.Token()
if tok == nil {
break
}
if err != nil {
return err
}
switch se := tok.(type) {
case xml.StartElement:
var value string
var valueAssigned bool
for _, attr := range se.Attr {
if attr.Name.Local == "value" {
value = attr.Value
valueAssigned = true
} else {
return fmt.Errorf("Invalid attribute %s", attr.Name.Local)
}
}
if !valueAssigned {
return fmt.Errorf("Valid attribute missing")
}
switch se.Name.Local {
case "code":
p.Code = value
case "valueBoolean":
if value == "true" {
p.Value = true
} else if value == "false" {
p.Value = false
} else {
return fmt.Errorf("Invalid string %s for Boolean value", value)
}
case "valueString", "valueCode", "valueUri":
p.Value = value
case "valueInteger":
if ival, err := strconv.ParseInt(value, 10, 32); err != nil {
return err
} else {
p.Value = ival
}
case "valueDecimal":
if dval, err := strconv.ParseFloat(value, 64); err != nil {
return err
} else {
p.Value = dval
}
default:
return fmt.Errorf("Invalid tag %s for property", se.Name.Local)
}
}
}
return nil
}
func main() {
r := strings.NewReader(xmldata)
type Properties struct {
List []Property `xml:"property"`
}
var properties Properties
d := xml.NewDecoder(r)
if err := d.Decode(&properties); err != nil {
fmt.Println(err.Error())
}
for _, p := range properties.List {
switch p.Value.(type) {
case bool:
if p.Value.(bool) {
fmt.Println(p.Code, "is true")
} else {
fmt.Println(p.Code, "is false")
}
default:
fmt.Println(p.Code, "=", p.Value)
}
}
}
输出是:
a is true
b = apple
c = 3.14159
关于go - 棘手的 Go xml.Unmarshal() 案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36939874/
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
有点边缘情况,但知道为什么&&=会这样吗?我正在使用1.9.2。obj=Object.newobj.instance_eval{@bar&&=@bar}#=>nil,expectedobj.instance_variables#=>[],soobjhasno@barinstancevariableobj.instance_eval{@bar=@bar&&@bar}#ostensiblythesameas@bar&&=@barobj.instance_variables#=>[:@bar]#whywouldthisversioninitialize@bar?为了比较,||=将实例变量初始
一般来说哪个更好用?:casenwhen'foo'result='bar'when'peanutbutter'result='jelly'when'stack'result='overflow'returnresult或map={'foo'=>'bar','peanutbutter'=>'jelly','stack'=>'overflow'}returnmap[n]更具体地说,什么时候应该使用案例陈述,什么时候应该只使用散列? 最佳答案 散列是一种数据结构,而case语句是一种控制结构。当你只是检索一些数据时,你应该使用散列(就像你
有没有办法在case语句的对象上隐式调用方法?即:classFoodefbar1enddefbaz...endend我希望能够做的是这样的事情......foo=Foo.newcasefoowhen.bar==1then"something"when.bar==2then"somethingelse"when.baz==3then"anotherthing"end...其中“when”语句正在评估case对象上方法的返回。这样的结构可能吗?如果是的话,我还没有弄清楚语法...... 最佳答案 FWIW,您根本不需要将对象传递给1.8
自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例
BigData/CloudComputing:基于阿里云技术产品的人工智能与大数据/云计算/分布式引擎的综合应用案例目录来理解技术交互流程目录一、云计算网站建设:部署与发布网站建设:简单动态网站搭建云服务器管理维护云数据库管理与数据迁移云存储:对象存储管理与安全超大流量网站的负载均衡二、大数据MOOC网站日志分析搭建企业级数据分析平台基于LBS的热点店铺搜索基于机器学习PAI实现精细化营销基于机器学习的客户流失预警分析使用DataV制作实时销售数据可视化大屏使用MaxCompute进行数据质量核查使用Quick BI制作图形化报表使用时间序列分解模型预测商品销量三、云安全云平台使用安全云上服务
这个问题在这里已经有了答案:HowdoIcreatemultiplesubmitbuttonsforthesameforminRails?(7个答案)关闭9年前。所以..'save'%>'library'%>然后在我的Controller中:with_actiondo|a|a.savedoenda.librarydoendend问题是只有一个操作被调用...两个submit_tags调用相同的操作...知道为什么吗?或者我如何获得两个按钮以将表单提交给两种不同的方法?
我是RubyonRails的新手。在Rails应用程序中,我看到了如下代码:在模型中,有一个类Car:classCar在controller中,有一个方法“some_method”classCarsController我有三个问题要问:1.在Controller的代码中@my_car.components,它有什么作用?什么是什么意思?2.“3.是否Car类必须显式定义has_many关联Componentclassif""isused或者是""可用于向Car添加新关联,即使关联未在Car中定义显式类? 最佳答案 编辑后:第1点@m
k=[1,2,3,4,5]forninkputsnifn==2k.delete(n)endendputsk.join(",")#Result:#1#2#4#5#[1,3,4,5]#Desired:#1#2#3#4#5#[1,3,4,5]同样的效果发生在另一个数组迭代器k.each上:k=[1,2,3,4,5]k.eachdo|n|putsnifn==2k.delete(n)endendputsk.join(",")具有相同的输出。发生这种情况的原因很清楚......Ruby实际上并没有遍历存储在数组中的对象,而是只是将它变成一个漂亮的数组索引迭代器,从索引0开始,每次增加索引直到结束。