golang XML与JSON互转及路径查询插件库mxj的使用
Golang XML与JSON互转及路径查询插件库mxj的使用
mxj是一个Go语言库,用于在map[string]interface{}、XML和JSON之间进行编码/解码,并通过键或键路径(包括通配符)从map中提取/修改值。
安装
使用go.mod安装:
go get github.com/clbanning/mxj/v2@v2.7
导入包:
import "github.com/clbanning/mxj/v2"
基本功能
XML与map[string]interface{}互转
type Map map[string]interface{}
// 从XML创建Map值
mv, err := NewMapXml(xmlValue) // 解码
xmlValue, err := mv.Xml() // 编码
// 从io.Reader读取XML创建Map
mv, err := NewMapXmlReader(xmlReader) // 重复调用可处理流
mv, raw, err := NewMapXmlReaderRaw(xmlReader) // 'raw'是解码的原始XML
// 将Map写入XML Writer
err := mv.XmlWriter(xmlWriter)
raw, err := mv.XmlWriterRaw(xmlWriter) // 'raw'是写入的原始XML
// 格式化输出
xmlValue, err := mv.XmlIndent(prefix, indent, ...)
err := mv.XmlIndentWriter(xmlWriter, prefix, indent, ...)
raw, err := mv.XmlIndentWriterRaw(xmlWriter, prefix, indent, ...)
批量处理XML
err := HandleXmlReader(xmlReader, mapHandler(Map), errHandler(error))
err := HandleXmlReaderRaw(xmlReader, mapHandler(Map, []byte), errHandler(error, []byte))
结构体与Map互转
mv, err := NewMapStruct(structVal) // 结构体转Map
err := mv.Struct(structPointer) // Map转结构体
提取和修改Map值
// 获取键的所有路径
paths := mv.PathsForKey(key)
// 获取键的最短路径
path := mv.PathForKeyShortest(key)
// 获取键的值
values, err := mv.ValuesForKey(key, subkeys)
values, err := mv.ValuesForPath(path, subkeys)
// 更新键的值
count, err := mv.UpdateValuesForPath(newVal, path, subkeys)
// 获取所有叶子节点
leafnodes := mv.LeafNodes()
leafvalues := mv.LeafValues()
// 创建新Map
newMap, err := mv.NewMap("oldKey_1:newKey_1", "oldKey_2:newKey_2", ..., "oldKey_N:newKey_N")
newMap, err := mv.NewMap("oldKey1", "oldKey3", "oldKey5") // 'mv'的子集
完整示例
XML转JSON示例
package main
import (
"encoding/json"
"fmt"
"github.com/clbanning/mxj/v2"
)
func main() {
xmlData := []byte(`
<person>
<name>John Doe</name>
<age>30</age>
<address>
<street>123 Main St</street>
<city>Anytown</city>
</address>
</person>
`)
// 将XML转换为Map
m, err := mxj.NewMapXml(xmlData)
if err != nil {
fmt.Println("Error converting XML to map:", err)
return
}
// 将Map转换为JSON
jsonData, err := json.MarshalIndent(m, "", " ")
if err != nil {
fmt.Println("Error converting map to JSON:", err)
return
}
fmt.Println("JSON output:")
fmt.Println(string(jsonData))
// 查询特定路径的值
values, err := m.ValuesForPath("person.address.street")
if err != nil {
fmt.Println("Error getting value for path:", err)
return
}
fmt.Println("\nStreet value:", values[0])
}
JSON转XML示例
package main
import (
"fmt"
"github.com/clbanning/mxj/v2"
)
func main() {
jsonData := []byte(`
{
"person": {
"name": "John Doe",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
}
`)
// 将JSON转换为Map
m, err := mxj.NewMapJson(jsonData)
if err != nil {
fmt.Println("Error converting JSON to map:", err)
return
}
// 将Map转换为XML
xmlData, err := m.XmlIndent("", " ")
if err != nil {
fmt.Println("Error converting map to XML:", err)
return
}
fmt.Println("XML output:")
fmt.Println(string(xmlData))
}
XML解析约定
使用NewMapXml():
- 属性通过在属性标签前加连字符"-"解析到map[string]interface{}值
- 如果元素是简单元素且有属性,元素值在map[string]interface{}表示中使用键"#text"
- XML注释、指令和处理指令被忽略
- 如果调用了CoerceKeysToLower(),结果键将变为小写
使用NewMapXmlSeq():
- 属性解析到map["#attr"]map[<attr_label>]map[string]interface{}值
- 除根元素外,所有元素都有"#seq"键
- 注释、指令和处理指令使用"#comment"、"#directive"和"#procinst"键解组到Map中
- 保留命名空间语法
XML编码约定
- ‘nil’ Map值编码为<tag/>
- 不能保证编码的XML文档与解码的相同。如果需要保持元素序列,请使用NewMapXmlSeq()和mv.XmlSeq()
更多关于golang XML与JSON互转及路径查询插件库mxj的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang XML与JSON互转及路径查询插件库mxj的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang中XML与JSON互转及mxj库使用指南
在Go语言中处理XML和JSON数据转换以及路径查询是一个常见需求,mxj库提供了强大的功能来实现这些操作。下面我将详细介绍如何使用mxj库进行XML与JSON的转换以及路径查询。
安装mxj库
首先需要安装mxj库:
go get github.com/clbanning/mxj
XML转JSON
package main
import (
"fmt"
"github.com/clbanning/mxj"
)
func main() {
xmlData := `
<person>
<name>John Doe</name>
<age>30</age>
<address>
<street>123 Main St</street>
<city>New York</city>
</address>
</person>
`
// 将XML转换为map
m, err := mxj.NewMapXml([]byte(xmlData))
if err != nil {
fmt.Println("XML解析错误:", err)
return
}
// 将map转换为JSON
jsonData, err := m.Json()
if err != nil {
fmt.Println("JSON转换错误:", err)
return
}
fmt.Println("转换后的JSON:")
fmt.Println(string(jsonData))
}
JSON转XML
package main
import (
"fmt"
"github.com/clbanning/mxj"
)
func main() {
jsonData := `{
"person": {
"name": "John Doe",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York"
}
}
}`
// 将JSON转换为map
m, err := mxj.NewMapJson([]byte(jsonData))
if err != nil {
fmt.Println("JSON解析错误:", err)
return
}
// 将map转换为XML
xmlData, err := m.Xml()
if err != nil {
fmt.Println("XML转换错误:", err)
return
}
fmt.Println("转换后的XML:")
fmt.Println(string(xmlData))
}
路径查询
mxj提供了强大的路径查询功能,类似于XPath:
package main
import (
"fmt"
"github.com/clbanning/mxj"
)
func main() {
xmlData := `
<persons>
<person id="1">
<name>John Doe</name>
<age>30</age>
</person>
<person id="2">
<name>Jane Smith</name>
<age>25</age>
</person>
</persons>
`
m, err := mxj.NewMapXml([]byte(xmlData))
if err != nil {
fmt.Println("XML解析错误:", err)
return
}
// 查询所有person的name
names, err := m.ValuesForKey("name")
if err != nil {
fmt.Println("查询错误:", err)
return
}
fmt.Println("所有姓名:")
for _, name := range names {
fmt.Println(name)
}
// 使用路径查询
path := "persons.person.#.name"
values, err := m.ValuesForPath(path)
if err != nil {
fmt.Println("路径查询错误:", err)
return
}
fmt.Println("\n通过路径查询的姓名:")
for _, value := range values {
fmt.Println(value)
}
}
高级特性
1. 属性处理
package main
import (
"fmt"
"github.com/clbanning/mxj"
)
func main() {
xmlData := `
<book id="123">
<title>Go Programming</title>
<author>John Doe</author>
</book>
`
m, err := mxj.NewMapXml([]byte(xmlData))
if err != nil {
fmt.Println("XML解析错误:", err)
return
}
// 获取属性
id, err := m.ValueForPath("book.-id")
if err != nil {
fmt.Println("获取属性错误:", err)
return
}
fmt.Println("Book ID:", id)
}
2. 自定义XML标签
package main
import (
"fmt"
"github.com/clbanning/mxj"
)
func main() {
jsonData := `{
"person": {
"name": "John Doe",
"age": 30
}
}`
m, err := mxj.NewMapJson([]byte(jsonData))
if err != nil {
fmt.Println("JSON解析错误:", err)
return
}
// 自定义根标签
xmlData, err := m.Xml("customRoot")
if err != nil {
fmt.Println("XML转换错误:", err)
return
}
fmt.Println("自定义根标签的XML:")
fmt.Println(string(xmlData))
}
注意事项
- XML转换为JSON时,属性会以"-"为前缀,如
-id
表示id属性 - 数组元素在路径中使用
#
表示,如persons.person.#.name
- 处理大型XML/JSON文件时,考虑使用流式处理方式
- 复杂嵌套结构可能需要特殊处理
mxj库提供了丰富的功能来处理XML和JSON数据,通过上述示例,您可以轻松实现两种格式的互转以及复杂的数据查询操作。