我正在尝试将存储在xml文档中的数据转换为备用数据存储。我尝试过各种技术,但没有一种技术证明有效。问题是xml没有固定的模式,并且具有非常规结构。 xml的样本如下
<?xml version="1.0"?>
<Data>
<f.1 value="field value" />
<f.2 value="other value" />
<f.3 value="field value 2" />
<withchildren>
<f.3.1 value="testvalue" />
<f.3.2 value="test value 3" />
</withchildren>
</Data>
理想情况下,最终结果应将结果存储在map[string]interface{}
中,以便将值转换为标准的多维JSON格式。
答案 0 :(得分:3)
如果你不确定结构goquery可能是你最好的选择。您的标签名称看起来有点奇怪我认为这只是样本。下面的代码使用键的标记名称并使用value属性,但您可以为任何结构修改它。
10.0
20.0
30.0
40.0
50.0
60.0
70.0
80.0
90.0
100.0
true
如果你真的不知道结构是什么,或者有多少嵌套元素可能会尝试这个递归版本。
如果您有多个具有相同名称的元素,则可以修改代码以添加带有键名称的数字。所以“tag1”,“tag2”等等。
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"strings"
)
func main() {
xml := `
<?xml version="1.0"?>
<Data>
<f1 value="field value"></f1>
<f2 value="other value"></f2>
<f3 value="field value 2"></f3>
<withchildren>
<f31 value="testvalue"></f31>
<f32 value="test value 3"></f32>
</withchildren>
</Data>
`
data := make(map[string]interface{})
reader := strings.NewReader(xml)
doc, _ := goquery.NewDocumentFromReader(reader)
children := doc.Find("Data").Children()
children.Each(func(i int, s *goquery.Selection) {
val, exists := s.Attr("value")
if exists {
data[goquery.NodeName(s)] = val
}
withchildren := s.Children()
if withchildren.Length() > 0 {
withchildren.Each(func(i int, s *goquery.Selection) {
val, exists := s.Attr("value")
if exists {
data[goquery.NodeName(s)] = val
}
})
}
})
fmt.Println(data)
}
还有一些我没有使用的Go包。
mxj将xml转换为map [string] interface {}
goxml2json从xml转换为json。