XML中的结构数组没有包装节点?

Posted

技术标签:

【中文标题】XML中的结构数组没有包装节点?【英文标题】:Array of struct in XML with no wrapping node? 【发布时间】:2021-12-20 07:03:18 【问题描述】:

我有一个客户有 XML,他们似乎想要一个库存数组,但每个项目一个接一个地列出,没有包装节点。

这是我正在做的一个示例,但每个项目都有一个包装节点。有没有办法让它们在“root”下一个接一个地列出来?

测试代码:

package main

import (
    "encoding/xml"
    "fmt"
    "os"
    "strconv"
)

func main() 
    type InventoryItem struct 
        XMLName  xml.Name
        ItemName string `xml:"Name"`
        ItemDescription string `xml:"Description"`
    

    type XMLEnvelop struct 
        XMLName   xml.Name        `xml:"root"`
        Inventory []InventoryItem `xml:"item"`
        Records   int             `xml:"records"`
    

    var items []InventoryItem

    for i := 1; i < 6; i++ 
        items = append(items, InventoryItemXMLName: xml.NameLocal: "item" + strconv.Itoa(i), ItemName: "Test " + strconv.Itoa(i), ItemDescription: "Description " + strconv.Itoa(i))
    

    v := &XMLEnvelopRecords: 1, Inventory: items

    output, err := xml.MarshalIndent(v, "", "    ")
    if err != nil 
        fmt.Printf("error: %v\n", err)
    

    // Write the output to check
    os.Stdout.Write(output)

    //Here is where I would make the request


测试输出:

<root>
    <item1>
        <Name>Test 1</Name>
        <Description>Description 1</Description>
    </item1>
    <item2>
        <Name>Test 2</Name>
        <Description>Description 2</Description>
    </item2>
    <item3>
        <Name>Test 3</Name>
        <Description>Description 3</Description>
    </item3>
    <item4>
        <Name>Test 4</Name>
        <Description>Description 4</Description>
    </item4>
    <item5>
        <Name>Test 5</Name>
        <Description>Description 5</Description>
    </item5>
    <records>1</records>
</root>

去游乐场:https://play.golang.org/p/3DRUaBFEQvC

这是他们似乎正在寻找的输出......无论出于何种原因。

<root>
    <Name>Test 1</Name>
    <Description>Description 1</Description>
    <Name>Test 2</Name>
    <Description>Description 2</Description>
    <Name>Test 3</Name>
    <Description>Description 3</Description>
    <Name>Test 4</Name>
    <Description>Description 4</Description>
    <Name>Test 5</Name>
    <Description>Description 5</Description>
    <records>1</records>
</root>

【问题讨论】:

您的测试输出和所需的输出都没有任何意义。它应该是&lt;root&gt;&lt;item&gt;&lt;Name&gt;&lt;/Name&gt;&lt;Desc...&gt;&lt;/Desc...&gt;&lt;/item&gt;&lt;item&gt;...&lt;/item&gt;&lt;/root&gt;,您不想为每个项目定义一个新标签,但您可以添加一个id 属性 【参考方案1】:

您可以实现自定义marshaler。

type InventoryItem struct 
    XMLName         xml.Name
    ItemName        string `xml:"Name"`
    ItemDescription string `xml:"Description"`


func (i InventoryItem) MarshalXML(e *xml.Encoder, start xml.StartElement) error 
    // Ignore the passed in `start` argument, it represents the
    // parent InventoryItem element of the Name and Description.

    // Declare types to represent the elements you want to encode,
    // initialize them to the item's field values and encode them.
    //
    // Use the ",chardata" option to tell the encoder to encode the
    // field's value directly rather than as a child element. 
    type Name struct 
        Value string `xml:",chardata"`
    
    if err := e.Encode(Namei.ItemName); err != nil 
        return err
    
    type Description struct 
        Value string `xml:",chardata"`
    
    return e.Encode(Descriptioni.ItemDescription)

https://play.golang.org/p/D4ZVr2sWZju

【讨论】:

以上是关于XML中的结构数组没有包装节点?的主要内容,如果未能解决你的问题,请参考以下文章

包装一组 XML 节点

XML节点InnerText包装方法

用其祖先节点/标签包装 XML 元素

在没有 DOM 的情况下过滤内存中的 XML 节点?

XML 从数组中搜索节点并将新数据添加到新节点

将 XML 转换为 Java 中的 JSON,其中子节点作为数组