Golang解析XML时无法同时处理Name/name大小写敏感与不敏感的结构体问题
Golang解析XML时无法同时处理Name/name大小写敏感与不敏感的结构体问题
// 结构体
type Test struct {
Name string `xml:"Name,attr"`
TestID string `xml:"ID",attr"`
}
<?xml version="1.0" encoding="UTF-8"?><Test Name="pankaj" TestID="12354"></Test>
或者 XML
<?xml version="1.0" encoding="UTF-8"?><Test name="pankaj" TestID="12354"></Test>
更多关于Golang解析XML时无法同时处理Name/name大小写敏感与不敏感的结构体问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
XML 通常是区分大小写的。Go 的 XML 包实现了这一点。
更多关于Golang解析XML时无法同时处理Name/name大小写敏感与不敏感的结构体问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,使用标准库encoding/xml解析XML时,默认情况下标签匹配是大小写敏感的。这意味着结构体字段的XML标签必须与XML文档中的属性名完全一致,包括大小写。当XML文档中属性名的大小写可能变化时,这会导致解析问题。
对于您提供的结构体Test,XML标签指定了属性名Name和ID。如果XML文档中使用的是小写的name,则无法正确解析。标准库没有直接支持大小写不敏感的XML解析,但可以通过以下方法处理:
方法1:使用自定义UnmarshalXML方法
通过实现xml.Unmarshaler接口,可以自定义XML解析逻辑,处理大小写不敏感的情况。
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type Test struct {
Name string `xml:"Name,attr"`
TestID string `xml:"ID,attr"`
}
func (t *Test) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
type Alias Test
aux := &struct {
*Alias
}{
Alias: (*Alias)(t),
}
for _, attr := range start.Attr {
switch strings.ToLower(attr.Name.Local) {
case "name":
t.Name = attr.Value
case "id":
t.TestID = attr.Value
}
}
return d.DecodeElement(aux, &start)
}
func main() {
xmlData1 := `<?xml version="1.0" encoding="UTF-8"?><Test Name="pankaj" ID="12354"></Test>`
xmlData2 := `<?xml version="1.0" encoding="UTF-8"?><Test name="pankaj" ID="12354"></Test>`
var test1 Test
if err := xml.Unmarshal([]byte(xmlData1), &test1); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Test1: Name=%s, TestID=%s\n", test1.Name, test1.TestID)
}
var test2 Test
if err := xml.Unmarshal([]byte(xmlData2), &test2); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Test2: Name=%s, TestID=%s\n", test2.Name, test2.TestID)
}
}
方法2:使用第三方库
如果标准库的限制过于严格,可以考虑使用第三方XML处理库,如libxml2的Go绑定,这些库可能提供更灵活的解析选项。
方法3:预处理XML字符串
在解析之前,将XML文档中的属性名统一转换为小写或大写,然后使用对应大小写的结构体标签。
package main
import (
"encoding/xml"
"fmt"
"regexp"
"strings"
)
type Test struct {
Name string `xml:"name,attr"`
TestID string `xml:"id,attr"`
}
func normalizeXMLAttributes(xmlData string) string {
re := regexp.MustCompile(`(\w+)=`)
return re.ReplaceAllStringFunc(xmlData, func(m string) string {
return strings.ToLower(m)
})
}
func main() {
xmlData := `<?xml version="1.0" encoding="UTF-8"?><Test Name="pankaj" ID="12354"></Test>`
normalizedXML := normalizeXMLAttributes(xmlData)
var test Test
if err := xml.Unmarshal([]byte(normalizedXML), &test); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Test: Name=%s, TestID=%s\n", test.Name, test.TestID)
}
}
注意事项
- 在自定义
UnmarshalXML方法中,需要确保正确处理所有可能的属性名变体。 - 预处理方法可能会影响性能,特别是在处理大型XML文档时。
- 结构体定义中,
TestID字段的XML标签应为xml:"ID,attr",而不是xml:"ID",attr"(注意多余的引号)。
以上方法可以解决XML属性名大小写不一致导致的解析问题。根据具体需求选择适合的方案。

