在golang中对带有XMLNS声明的XML根令牌进行编码/解码。

huangapple go评论81阅读模式
英文:

Encoding/decoding XML root token with XMLNS declaration in golang

问题

我正在尝试使用Go语言的encoding/xml包对XML令牌进行编码和解码。所涉及的XML令牌具有命名空间、xmlns属性以及标签上命名空间的声明(这里的示例是XMPP流开始元素)。它是XMPP流的根元素:

<?xml version="1.0" encoding="UTF-8"?>
<stream:stream
       from='juliet@im.example.com'
       to='im.example.com'
       version='1.0'
       xml:lang='en'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'>

(忽略处理指令;我只是留下它来说明这是根元素)

我希望能够从结构体中读取/写入此令牌,因此我使用decoder.Token()将其作为xml.StartElement获取,并手动将所有属性复制到结构体中。然后,我使用encoder.Encode(thestruct)将其写出,但总是得到奇怪的结果(xmlns是错误的,起始标签永远不是stream:stream,即使XMLName是正确的)。

应如何修改此结构体,以便能够对类似上述XML的内容进行编码和解码?

type stream struct {
    STo         string   `xml:"to,attr"`
    SFrom       string   `xml:"from,attr"`
    Version     string   `xml:"version,attr"`
    Xmlns       string   `xml:"xmlns,attr"`
    Lang        string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr"`
    Id          string   `xml:"id,attr"`
    XmlnsStream string   `xml:"xmlns stream,attr"`
    XMLName     xml.Name `xml:"http://etherx.jabber.org/streams stream"`
}
英文:

I am attempting to encode and decode an XML token in Go using the encoding/xml package. The XML token in question has a namespace, an xmlns attribute, and a namespace declaration for the namespace on the tag (the example here is an XMPP stream start element). It is the root element of an XMPP stream:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;stream:stream
       from=&#39;juliet@im.example.com&#39;
       to=&#39;im.example.com&#39;
       version=&#39;1.0&#39;
       xml:lang=&#39;en&#39;
       xmlns=&#39;jabber:client&#39;
       xmlns:stream=&#39;http://etherx.jabber.org/streams&#39;&gt;

(Ignore the processing instruction; I merely left that to illustrate that this is the root element)

I want to be able to read/write this token from a struct, so I fetch it as an xml.StartElement with decoder.Token() and manually copy all the attributes over to the struct. I then write it out with encoder.Encode(thestruct), but always get funny results (The xmlns is wrong, and the start tag is never stream:stream even though the XMLName is correct).

How should this struct be modified to be able to encode and decode to and from something like the above XML?

type stream struct {
	STo         string   `xml:&quot;to,attr&quot;`
	SFrom       string   `xml:&quot;from,attr&quot;`
	Version     string   `xml:&quot;version,attr&quot;`
	Xmlns       string   `xml:&quot;xmlns,attr&quot;`
	Lang        string   `xml:&quot;http://www.w3.org/XML/1998/namespace lang,attr&quot;`
	Id          string   `xml:&quot;id,attr&quot;`
	XmlnsStream string   `xml:&quot;xmlns stream,attr&quot;`
	XMLName     xml.Name `xml:&quot;http://etherx.jabber.org/streams stream&quot;`
}

答案1

得分: 1

你得到了正确的结果,因为:

<stream:stream
      xmlns:stream='http://etherx.jabber.org/streams' />

<stream xmlns='http://etherx.jabber.org/streams' />

是相同的。

Jabber的XML非常复杂,所以如果你想得到正确的XMPP XML,可能需要编写自己的编码器。

顺便说一下,如果你看一下Golang的XMPP实现,你会发现它们都使用自己的编码(通常也包括解码)。

英文:

You get correct results, because:

&lt;stream:stream
      xmlns:stream=&#39;http://etherx.jabber.org/streams&#39; /&gt;

is the same as

&lt;stream xmlns=&#39;http://etherx.jabber.org/streams&#39; /&gt;

Jabber's XMLs are pretty sophisticated, so if you wan't to end up with correct XMPP XMLs, you probably need to write your own encoder.

By the way, if you look at Golang XMPP implementations you'll see they all use own encoding (and, often, decoding).

huangapple
  • 本文由 发表于 2014年11月27日 06:48:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/27160204.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定