给子元素添加属性而不生成新的 XML 元素。

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

Add attribute to the child without generating new XML element

问题

如何使用Go XML包创建这个XML呢?

<Files><File width="200" height="100">somevaluehere</File></Files>

这比你想象的要困难,例如:

type Video struct {
    Files Files `xml:"Files"`
}

type Files struct {
    Width  string `xml:"Width,attr"`
    Height string `xml:"Height,attr"`
    File   string `xml:",chardata"`
}

输出结果是:

<Video><Files Width="640" Height="480"><File>somevalue</File></Files></Video>

而我想要的是:

<Video><Files><File Width="640" Height="480">somevalue</File></Files></Video>
英文:

How can I create this XML using the Go XML package?

&lt;Files&gt;&lt;File width=&quot;200&quot; height=&quot;100&quot;&gt;somevaluehere&lt;/File&gt;&lt;/Files&gt;

It is harder than you may think, for example:

type Video struct {
    Files Files `xml:&quot;Files&quot;`
}

type Files struct {
	Width  string `xml:&quot;Width,attr&quot;`
	Height string `xml:&quot;Height,attr&quot;`
	File   string `xml:&quot;File&quot;`
}

the output is:

&lt;Video&gt;&lt;Files Width=&quot;640&quot; Height=&quot;480&quot;&gt;&lt;File&gt;somevalue&lt;/File&gt;&lt;/Files&gt;&lt;/Video&gt;

And I want:

&lt;Video&gt;&lt;Files&gt;&lt;File Width=&quot;640&quot; Height=&quot;480&quot;&gt;somevalue&lt;/File&gt;&lt;/Files&gt;&lt;/Video&gt;

答案1

得分: 2

你想要将Video.Files渲染为<Video><Files><File>标签,因此在标签中指明这一点:

type Video struct {
    Files Files `xml:"Files>File"`
}

type Files struct {
    Width  string `xml:"Width,attr"`
    Height string `xml:"Height,attr"`
    File   string `xml:",chardata"`
}

并且你希望Files.File的值成为标签的字符数据,也在标签中指明这一点:

type Files struct {
    Width  string `xml:"Width,attr"`
    Height string `xml:"Height,attr"`
    File   string `xml:",chardata"`
}

进行测试:

v := Video{
    Files: Files{
        Width:  "640",
        Height: "480",
        File:   "someValue",
    },
}
out, err := xml.Marshal(v)
if err != nil {
    panic(err)
}
fmt.Println(string(out))

输出结果为:

<Video><Files><File Width="640" Height="480">someValue</File></Files></Video>

如果<Files>内部可能有多个<File>元素,我会将Video.Files定义为切片:

type Video struct {
    Files []File `xml:"Files>File"`
}

type File struct {
    Width  string `xml:"Width,attr"`
    Height string `xml:"Height,attr"`
    File   string `xml:",chardata"`
}

进行测试:

v := Video{
    Files: []File{
        {
            Width:  "640",
            Height: "480",
            File:   "someValue",
        },
        {
            Width:  "320",
            Height: "240",
            File:   "otherValue",
        },
    },
}
out, err := xml.Marshal(v)
if err != nil {
    panic(err)
}
fmt.Println(string(out))

输出结果为:

<Video><Files><File Width="640" Height="480">someValue</File><File Width="320" Height="240">otherValue</File></Files></Video>
英文:

You want Video.Files to be rendered into &lt;Video&gt;&lt;Files&gt;&lt;File&gt; tag, so indicate this in the tag:

type Video struct {
	Files Files `xml:&quot;Files&gt;File&quot;`
}

And you want the Files.File value to be the tag's char data, also indicate this in the tag:

type Files struct {
	Width  string `xml:&quot;Width,attr&quot;`
	Height string `xml:&quot;Height,attr&quot;`
	File   string `xml:&quot;,chardata&quot;`
}

Testing it:

v := Video{
	Files: Files{
		Width:  &quot;640&quot;,
		Height: &quot;480&quot;,
		File:   &quot;someValue&quot;,
	},
}
out, err := xml.Marshal(v)
if err != nil {
	panic(err)
}
fmt.Println(string(out))

Which outputs (try it on the Go Playground):

&lt;Video&gt;&lt;Files&gt;&lt;File Width=&quot;640&quot; Height=&quot;480&quot;&gt;someValue&lt;/File&gt;&lt;/Files&gt;&lt;/Video&gt;

If there could me multiple &lt;File&gt; elements inside &lt;Files&gt;, I would make Video.Files a slice:

type Video struct {
	Files []File `xml:&quot;Files&gt;File&quot;`
}

type File struct {
	Width  string `xml:&quot;Width,attr&quot;`
	Height string `xml:&quot;Height,attr&quot;`
	File   string `xml:&quot;,chardata&quot;`
}

Testing it:

v := Video{
	Files: []File{
		{
			Width:  &quot;640&quot;,
			Height: &quot;480&quot;,
			File:   &quot;someValue&quot;,
		},
		{
			Width:  &quot;320&quot;,
			Height: &quot;240&quot;,
			File:   &quot;otherValue&quot;,
		},
	},
}
out, err := xml.Marshal(v)
if err != nil {
	panic(err)
}
fmt.Println(string(out))

Which outputs (try it on the Go Playground):

&lt;Video&gt;&lt;Files&gt;&lt;File Width=&quot;640&quot; Height=&quot;480&quot;&gt;someValue&lt;/File&gt;&lt;File Width=&quot;320&quot; Height=&quot;240&quot;&gt;otherValue&lt;/File&gt;&lt;/Files&gt;&lt;/Video&gt;

huangapple
  • 本文由 发表于 2022年2月3日 20:17:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/70971154.html
匿名

发表评论

匿名网友

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

确定