Golang: 在 encoding/xml 中的 UnmarshalXMLAttr 函数

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

Golang: UnmarshalXMLAttr in encoding/xml

问题

我正在尝试解析一些XML,希望以特殊的方式解析属性。我尝试使用UnmarshalerAttr接口,但无法使其工作。使用以下代码,我只得到了'Castle'的输出。

  1. package main
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "strings"
  6. )
  7. type Show struct {
  8. Title string `xml:"Title,attr"`
  9. }
  10. func (s *Show) UnmarshalXMLAttr(attr xml.Attr) error {
  11. fmt.Printf("Parsing attribute '%s', with value '%s'", attr.Name.Local, attr.Value)
  12. s.Title = strings.ToUpper(attr.Value)
  13. return nil
  14. }
  15. func main() {
  16. b := []byte(`<Series Title="Castle"></Series>`)
  17. var show Show
  18. xml.Unmarshal(b, &show)
  19. fmt.Println(show)
  20. }

有什么想法吗?

英文:

I'm trying to unmarshal some XML, where I want to parse the attributes in a special way. I have tried using the UnmarshalerAttr interface but I cannot get it working. Using the following code, the only output I get is '{Castle}'

<!-- language: lang-golang -->

  1. package main
  2. import (
  3. &quot;encoding/xml&quot;
  4. &quot;fmt&quot;
  5. &quot;strings&quot;
  6. )
  7. type Show struct {
  8. Title string `xml:&quot;Title,attr&quot;`
  9. }
  10. func (s *Show) UnmarshalXMLAttr(attr xml.Attr) error {
  11. fmt.Printf(&quot;Parsing attribute &#39;%s&#39;, with value &#39;%s&#39;&quot;, attr.Name.Local, attr.Value)
  12. s.Title = strings.ToUpper(attr.Value)
  13. return nil
  14. }
  15. func main() {
  16. b := []byte(`&lt;Series Title=&quot;Castle&quot;&gt;&lt;/Series&gt;`)
  17. var show Show
  18. xml.Unmarshal(b, &amp;show)
  19. fmt.Println(show)
  20. }

Any ideas?

答案1

得分: 2

属性unmarshaler需要是标题的类型,而不是show的类型。这是修复后的版本:

首先,我们创建一个“伪类型”,它只是包装了字符串并实现了接口。

  1. type title string

现在我们将标题字段定义为我们的类型,而不仅仅是一个字符串。

这将为该属性调用我们的unmarshaler。

  1. type Show struct {
  2. Title title `xml:"Title,attr"`
  3. }

现在是我们类型的自定义unmarshaler:

  1. func (s *title) UnmarshalXMLAttr(attr xml.Attr) error {
  2. fmt.Printf("解析属性'%s',值为'%s'", attr.Name.Local, attr.Value)
  3. *s = title(strings.ToUpper(attr.Value))
  4. return nil
  5. }

其余部分保持不变:

  1. func main() {
  2. b := []byte(`<Series Title="Castle"></Series>`)
  3. var show Show
  4. xml.Unmarshal(b, &show)
  5. fmt.Println(show)
  6. }

http://play.golang.org/p/6J4UZ7BeG1

英文:

The attribute unmarshaler needs to be the type of the title, not the show. here's a fixed version:

First, we create a "faux type" that just wraps string and implements the interface

  1. type title string

Now we define the title field as our type, and not just a string.

This will call our unmarshaler for this attribute

  1. type Show struct {
  2. Title title `xml:&quot;Title,attr&quot;`
  3. }

And now the custom unmashaler for for our type:

  1. func (s *title) UnmarshalXMLAttr(attr xml.Attr) error {
  2. fmt.Printf(&quot;Parsing attribute &#39;%s&#39;, with value &#39;%s&#39;&quot;, attr.Name.Local, attr.Value)
  3. *s = title(strings.ToUpper(attr.Value))
  4. return nil
  5. }

The rest remains the same:

  1. func main() {
  2. b := []byte(`&lt;Series Title=&quot;Castle&quot;&gt;&lt;/Series&gt;`)
  3. var show Show
  4. xml.Unmarshal(b, &amp;show)
  5. fmt.Println(show)
  6. }

http://play.golang.org/p/6J4UZ7BeG1

huangapple
  • 本文由 发表于 2014年7月27日 18:46:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/24980166.html
匿名

发表评论

匿名网友

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

确定