当对某些XML数据使用umarshal时,我在访问名称空间标记中的属性时遇到了困难。我正在尝试完成的一个工作示例是代码的第14行,它演示了如何将属性name从<cpe-item>标记加载到CPE结构的Name字段中。
但是,在第19行(将name属性从<cpe23: cpe23-item>标记加载到CPE23结构的Name字段)这样的名称间隔标记中,执行相同的操作不起作用--找不到任何值。
我没有看到这两种行为之间的差异,以及为什么其中一种失败而另一种失败。
package main
import (
"encoding/xml"
"fmt"
)
type CPEs struct {
XMLName xml.Name `xml:"cpe-list"`
CPEs []CPE `xml:"cpe-item"`
}
type CPE struct {
Name string `xml:"name,attr"`
CPE23 CPE23 `xml:"cpe23: cpe23-item"`
}
type CPE23 struct {
Name string `xml:"cpe23: cpe23-item,name,attr"`
}
func main() {
var cpes CPEs
contents := `
<cpe-list xmlns:meta="http://scap.nist.gov/schema/cpe-dictionary-metadata/0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cpe-23="http://scap.nist.gov/schema/cpe-extension/2.3" xmlns="http://cpe.mitre.org/dictionary/2.0" xmlns:config="http://scap.nist.gov/schema/configuration/0.1" xmlns:ns6="http://scap.nist.gov/schema/scap-core/0.1" xmlns:scap-core="http://scap.nist.gov/schema/scap-core/0.3" xsi:schemaLocation="http://scap.nist.gov/schema/cpe-extension/2.3 https://scap.nist.gov/schema/cpe/2.3/cpe-dictionary-extension_2.3.xsd http://cpe.mitre.org/dictionary/2.0 https://scap.nist.gov/schema/cpe/2.3/cpe-dictionary_2.3.xsd http://scap.nist.gov/schema/cpe-dictionary-metadata/0.2 https://scap.nist.gov/schema/cpe/2.1/cpe-dictionary-metadata_0.2.xsd http://scap.nist.gov/schema/scap-core/0.3 https://scap.nist.gov/schema/nvd/scap-core_0.3.xsd http://scap.nist.gov/schema/configuration/0.1 https://scap.nist.gov/schema/nvd/configuration_0.1.xsd http://scap.nist.gov/schema/scap-core/0.1 https://scap.nist.gov/schema/nvd/scap-core_0.1.xsd">
<cpe-item name="I'm the cpe name!"><!--I can parse this attribute-->
<title>I'm the title!</title>
<references>
<reference href="https://example.com">Example</reference>
<reference href="https://example2.com">Example 2</reference>
</references>
<cpe-23:cpe23-item name="CPE 2.3 name!"/><!--I can't parse this attribute-->
</cpe-item>
</cpe-list>`
xml.Unmarshal([]byte(contents), &cpes)
for i := 0; i < len(cpes.CPEs); i++ {
fmt.Println("CPE Name: " + cpes.CPEs[i].Name)
fmt.Println("CPE23 Name: " + cpes.CPEs[i].CPE23.Name)
}
}发布于 2020-06-28 19:36:52
但是,只需从CPE23字段的标记中移除命名空间,就可以使代码工作:
type CPE struct {
Name string `xml:"name,attr"`
CPE23 CPE23 `xml:"cpe23-item"`
}
type CPE23 struct {
Name string `xml:"name,attr"`
}...or通过用完整的命名空间作为标记名的前缀,用空格隔开:
type CPE struct {
Name string `xml:"name,attr"`
CPE23 CPE23 `xml:"http://scap.nist.gov/schema/cpe-extension/2.3 cpe23-item"`
}参见此去玩
通过查看encoding/xml包的源代码,可以看到令牌程序以<ns:foo> (其中xmlns:ns="http://mynamespace.com" )的形式将xml元素标记读入表单中的xml.Name结构中:
xml.Name{
Space: "http://mynamespace.com",
Local: "foo"
}然后根据这两个字段解析目标结构上的标记。如果您的struct标记上没有命名空间,那么它只匹配Local的值。
https://stackoverflow.com/questions/62625631
复制相似问题