Golang XML marshal两个相同的属性

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

Golang XML marshal two identical attributes

问题

我被迫使用一些设计不良的 XML,我正在尝试将这个 XML 读入到一个 Go 结构中。这里是一些示例数据:

<?xml version="1.0" encoding="UTF-8"?>
<dictionary>
    
    <direction from="lojban" to="English">
        <valsi word="cipni" type="gismo">
            <rafsi>cpi</rafsi>
            <definition>x1 is a bird of species x2</definition>
            <notes></notes>
        </valsi>
        ...
    </direction>

    <direction from="English" to="lojban">
        <nlword word="eagle" valsi="atkuila" />
        <nlword word="hawk" sense="bird" valsi="aksiptrina" />
        ...
    </direction>
    
</dictionary>

我的问题是,我无法同时读取 <valsi> 节点和 <nlword> 节点,因为它们都包含属性 "word":

main.NLWord 字段 "Word" 的标签 "word,attr" 与字段 "Valsi" 的标签 "word,attr" 冲突

我开始觉得解组可能不是正确的方法,因为我理想情况下会以不同的方式组织数据。我应该使用其他方法读取 XML 并手动构建数据结构吗?

type Valsi struct {
    Word  string   `xml:"word,attr"`
    Type  string   `xml:"type,attr"`
    Def   string   `xml:"definition"`
    Notes string   `xml:"notes"`
    Class string   `xml:"selmaho"`
    Rafsi []string `xml:"rafsi"`
}

// 制作这个 XML 结构的人需要受到痛苦的教训...
type Collection struct {
    From  string  `xml:"from"`
    To    string  `xml:"to"`
    Valsi []Valsi `xml:"valsi"`
}

type Vlaste struct {
    Direction []Collection `xml:"direction"`
}

var httpc = &http.Client{}

func parseXML(data []byte) Vlaste {
    vlaste := Vlaste{}
    err := xml.Unmarshal(data, &vlaste)
    if err != nil {
        fmt.Println("Problem Decoding!")
        log.Fatal(err)
    }
    return vlaste
}

希望这可以帮助到你。

英文:

I'm forced to work with some poorly designed XML, I'm trying to read this XML into a Go structure. Here's some sample data:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;dictionary&gt;
    
    &lt;direction from=&quot;lojban&quot; to=&quot;English&quot;&gt;
        &lt;valsi word=&quot;cipni&quot; type=&quot;gismo&quot;&gt;
            &lt;rafsi&gt;cpi&lt;/rafsi&gt;
            &lt;definition&gt;x1 is a bird of species x2&lt;/definition&gt;
            &lt;notes&gt;&lt;/notes&gt;
        &lt;/valsi&gt;
        ...
    &lt;/direction&gt;

    &lt;direction from=&quot;English&quot; to=&quot;lojban&quot;&gt;
        &lt;nlword word=&quot;eagle&quot; valsi=&quot;atkuila&quot; /&gt;
        &lt;nlword word=&quot;hawk&quot; sense=&quot;bird&quot; valsi=&quot;aksiptrina&quot; /&gt;
        ...
    &lt;/direction&gt;
    
&lt;/dictionary&gt;

My issue is I can either read in <valsi> nodes or <nlword> because they both contain the attribute "word":

main.NLWord field &quot;Word&quot; with tag &quot;word,attr&quot; conflicts with field &quot;Valsi&quot; with tag &quot;word,attr&quot;

I'm starting to think unmarshalling may be the wrong approach as I'd ideally structure the data differently. Should I read the XML in using some other method and build up data structures manually?

type Valsi struct {
	Word  string   `xml:&quot;word,attr&quot;`
	Type  string   `xml:&quot;type,attr&quot;`
	Def   string   `xml:&quot;definition&quot;`
	Notes string   `xml:&quot;notes&quot;`
	Class string   `xml:&quot;selmaho&quot;`
	Rafsi []string `xml:&quot;rafsi&quot;`
}

//Whoever made this XML structure needs to be painfully taught a lesson...
type Collection struct {
	From  string  `xml:&quot;from&quot;`
	To    string  `xml:&quot;to&quot;`
	Valsi []Valsi `xml:&quot;valsi&quot;`
}

type Vlaste struct {
	Direction []Collection `xml:&quot;direction&quot;`
}

var httpc = &amp;http.Client{}

func parseXML(data []byte) Vlaste {
	vlaste := Vlaste{}
	err := xml.Unmarshal(data, &amp;vlaste)
	if err != nil {
		fmt.Println(&quot;Problem Decoding!&quot;)
		log.Fatal(err)
	}
	return vlaste
}

答案1

得分: 2

我可能没有完全理解你的问题,但是对于我来说,以下结构在我这里运行良好(根据你修改的示例):

type Valsi struct {
    Word  string   `xml:"word,attr"`
    Type  string   `xml:"type,attr"`
    Def   string   `xml:"definition"`
    Notes string   `xml:"notes"`
    Class string   `xml:"selmaho"`
    Rafsi []string `xml:"rafsi"`
}

type NLWord struct {
    Word  string   `xml:"word,attr"`
    Sense string   `xml:"sense,attr"`
    Valsi string   `xml:"valsi,attr"`
}

type Collection struct {
    From    string    `xml:"from,attr"`
    To      string    `xml:"to,attr"`
    Valsi   []Valsi   `xml:"valsi"`
    NLWord  []NLWord  `xml:"nlword"`
}

type Vlaste struct {
    Direction []Collection `xml:"direction"`
}

在这个结构中,Collection 可以有 Valsi 值和 NLWord 值。
然后,你可以根据 From/ToValsiNLWord 的长度来决定如何处理数据。

英文:

I may not have grasped what your problem is but the following structure works fine for me
(your modified example on play):

type Valsi struct {
    Word  string   `xml:&quot;word,attr&quot;`
    Type  string   `xml:&quot;type,attr&quot;`
    Def   string   `xml:&quot;definition&quot;`
    Notes string   `xml:&quot;notes&quot;`
    Class string   `xml:&quot;selmaho&quot;`
    Rafsi []string `xml:&quot;rafsi&quot;`
}

type NLWord struct {
    Word  string   `xml:&quot;word,attr&quot;`
    Sense string   `xml:&quot;sense,attr&quot;`
    Valsi string   `xml:&quot;valsi,attr&quot;`
}

type Collection struct {
    From  string    `xml:&quot;from,attr&quot;`
    To    string    `xml:&quot;to,attr&quot;`
    Valsi []Valsi   `xml:&quot;valsi&quot;`
    NLWord []NLWord `xml:&quot;nlword&quot;`
}

type Vlaste struct {
    Direction []Collection `xml:&quot;direction&quot;`
}

In this structure, Collection can have Valsi values as well as NLWord values.
You can then decide, depending on From/To or the length of either Valsi or NLWord how to handle the data.

huangapple
  • 本文由 发表于 2013年10月18日 06:36:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/19438495.html
匿名

发表评论

匿名网友

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

确定