Golang XML unmarshalling问题:本地名称冲突失败 [英] Golang XML unmarshalling issue: local name collisions fail
问题描述
我得到不正确的行为(或者我做错了什么)。
golang XML demarshalling似乎并不处理本地名称冲突的特定情况。
也就是说,你有一个元素有两个子元素,它们都有相同的本地名称(book),但没有名称空间(或默认或空),另一个具有明确的名称空间。 / p>
对于(一个人为的)例子:
< library
xmlns:lib =http://foobar.com/ns/library>
< lib:book>
AAA
< / lib:book>
< book>
ZZZ
< / book>
< library>
如果我使用以下结构体来表示:
type Library_Type struct {
Book string`xml:book,omitemptyjson:,omitempty`
Book_lib string`xml:http: //foobar.com/ns/library book,omitemptyjson:,omitempty`
Lib字符串`xml:xmlns lib,attr`
}
尝试去组合,它根本不起作用:资料来源: http://play.golang.org/p/YW2XpTVRs5
输出:
{Lib:}
pre>
{Lib:}
然而,如果我在结构中注释掉'Book string': $ b
输出:
{Book_lib:\\\
AAA\\\
,Lib:http://foobar.com/ns/library}
如果我将'Book_lib '...: http://play.golang.org/p/u_Up9X9YMp
输出:
{Book:\\\
ZZZ\ n,Lib:http://foobar.com/ns/library}
如果我在'Book'前添加一个空格:
From:
书本字符串`xml: omitemptyjson:,omitempty`
收件人:
Book string`xml:book,omitemptyjson:,omitempty`
但是,添加2个空格(可以解释为第一个空格是命名空间,第二个空格是空格分隔;当没有命名空间时,调用xml.StartElement.Name.Space等于):
收件人:
Book string`xml:book,omitemptyjson:,omitempty`
http://play.golang.org/p/Br_WBR3U8K 输出:
{Book_lib:\\\
AAA \\ \\ n,Lib:http://foobar.com/ns/library}
如果我有两个明确的名称空间,问题消失(输出是预期的输出): http:/ /play.golang.org/p/llpMuC0SV8
输出:
{Book_bin:\\\
ZZZ\\\
,Book_lib:\\\
AAA\\\
,Lib:http://foobar.com/ns/library ,Bin:http://foobar.com/ns/bin}
所以,除非我在这里做错了什么,XML的使用情况是混合使用默认值(empt y)名称空间和显式命名空间与本地名称冲突似乎不起作用,这是一个错误。
但是,如果你能找到我的解决方法,我将不胜感激。
解决方案这个问题非常有趣,我必须做一些研究才能得到它。
- 您需要使用
您必须为书籍使用单独的结构
,chardata
作为实际值。 a href =http://play.golang.org/p/BXdill2d6v =nofollow> playground
类型库结构{
XMLName xml.Name`xml:library`
Entry [] Book`xml:book`
}
类型结构{
XMLName xml.Name`xml:book`
名称字符串`xml:,chardata`
}
I am getting incorrect behaviour (or I am doing something wrong). The golang XML demarshalling does not appear to handle a specific case of local name collisions. That is, where you have one element that has 2 child elements, both with the same local name ("book") but one with no namespace (or default or empty), and the other with an explicit namespace.
For (a contrived) example:
<library xmlns:lib="http://foobar.com/ns/library"> <lib:book> AAA </lib:book> <book> ZZZ </book> <library>
If I use the following struct to represent this:
type Library_Type struct { Book string `xml:"book,omitempty" json:",omitempty"` Book_lib string `xml:"http://foobar.com/ns/library book,omitempty" json:",omitempty"` Lib string `xml:"xmlns lib,attr"` }
And try to demarshal, it does not work at all: Source: http://play.golang.org/p/YW2XpTVRs5
Output:
{"Lib":""} {"Lib":""}
However, if I comment out the 'Book string' in the struct: http://play.golang.org/p/BRv6tUNreM
Output:
{"Book_lib":"\n AAA\n ","Lib":"http://foobar.com/ns/library"}
If I comment out the 'Book_lib'...: http://play.golang.org/p/u_Up9X9YMp
Output:
{"Book":"\n ZZZ\n ","Lib":"http://foobar.com/ns/library"}
If I add a space in front of 'Book': From:
Book string `xml:"book,omitempty" json:",omitempty"`
To:
Book string `xml:" book,omitempty" json:",omitempty"`
However, adding 2 spaces (which could be interpreted as the first space being the namespace, and the second space whitespace separation; when there is no namespace, calling xml.StartElement.Name.Space equals ""):
To:
Book string `xml:" book,omitempty" json:",omitempty"`
http://play.golang.org/p/Br_WBR3U8K
Output:
{"Book_lib":"\n AAA\n ","Lib":"http://foobar.com/ns/library"}
If I have two exlicit name spaces, the problem goes away (the output is the expected output): http://play.golang.org/p/llpMuC0SV8
Output:
{"Book_bin":"\n ZZZ\n ","Book_lib":"\n AAA\n ","Lib":"http://foobar.com/ns/library","Bin":"http://foobar.com/ns/bin"}
So, unless I am doing something wrong here, the use case where XML has a mix of default (empty) namespace and explicit namespaces with local name collisions appears to not work and this is a bug.
But if you could find me a way around this I would appreciate it.
解决方案This question is very interesting, and I actually had to do some research to get it.
You will have to use a separate struct for the books
You will need to use
,chardata
for the actual value.type Library struct { XMLName xml.Name `xml:"library"` Entry []Book `xml:"book"` } type Book struct { XMLName xml.Name `xml:"book"` Name string `xml:",chardata"` }
这篇关于Golang XML unmarshalling问题:本地名称冲突失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!