如何解组动态 XML 数据来构造?

How to unmarshal dynamic XML data to struct?

我有一个 XML 数据,其中有一些具有动态元素名称的重复数据,如下所示。

<Ht>
<Criteria>
    <ADNode_1>2</ADNode_1>
    <CDNode_1>2</CDNode_1>
    <IFNode_1>0</IFNode_1>
    <ADNode_2>2</ADNode_2>
    <CDNode_2>0</CDNode_2>
    <IFNode_2>0</IFNode_2>
    <ADNode_3>0</ADNode_3>
    <CDNode_3>0</CDNode_3>
    <IFNode_3>0</IFNode_3>
</Criteria>
<session id="1056134770841202228344907">
    <Htd ID="21170">
        <Data_1>
            <Info Count="2"></Info>
            <Data Id="iV29308/B2/R1">
                <Type>TR1</Type>
            </Data>
            <Data Id="iV29308/B3/R1">
                <Type>TR1</Type>
            </Data>
            <Data Id="iV29308/B4/R1">
                <Type>TR1</Type>
            </Data>
            <Data Id="iV29308/B6/R1">
                <Type>TR1</Type>
            </Data>
        </Data_1>
        <Data_2>
            <Info Count="2"></Info>
            <Data Id="iV29308/B2/R1">
                <Type>TR2</Type>
            </Data>
            <Data Id="iV29308/B3/R1">
                <Type>TR2</Type>
            </Data>
            <Data Id="iV29308/B4/R1">
                <Type>TR2</Type>
            </Data>
            <Data Id="iV29308/B6/R1">
                <Type>TR3</Type>
            </Data>
        </Data_2>
    </Htd>
</session>

我可以为 <ADNode_1><ADNode_2><ADNode_3><Data_1><Data_2> 创建单独的结构,但可以有 n 个这些节点。 喜欢下面

<ADNode_1>2</ADNode_1>
<ADNode_2>2</ADNode_2>
<ADNode_3>2</ADNode_3>
<ADNode_n>2</ADNode_n>

<Data_1></Data_1>
<Data_2></Data_2>
<Data_3></Data_3>
<Data_n></Data_n>

如何为这些节点创建具有 n 个节点或元素的结构?

这是游乐场link我正在努力工作。

通常对于这些情况,您可以在 Go 中使用切片来“收集”元素,并使用 ,any 选项将您没有映射的所有内容放入其中。为了能够识别来源,请使用 XMLName xml.Name 字段,该字段将保留其来源的 XML 标签的名称。

例如,您可以这样建模 XML:

type Ht struct {
    Criteria struct {
        Nodes []struct {
            XMLName xml.Name
            Content string `xml:",chardata"`
        } `xml:",any"`
    }
    Session struct {
        ID  string `xml:"id,attr"`
        Htd struct {
            ID    string `xml:"ID,attr"`
            DataX []struct {
                XMLName xml.Name
                Info    struct {
                    Count int `xml:"Count,attr"`
                }
                DataNodes []struct {
                    XMLName xml.Name
                    ID      string `xml:"Id,attr"`
                    Type    string
                } `xml:",any"`
            } `xml:",any"`
        }
    } `xml:"session"`
}

对其进行解析并重新编码将保留所有元素:

var ht Ht
if err := xml.Unmarshal([]byte(src), &ht); err != nil {
    panic(err)
}

result, err := xml.MarshalIndent(ht, "", "  ")
if err != nil {
    panic(err)
}

fmt.Println(string(result))

这将输出(在 Go Playground 上尝试):

<Ht>
  <Criteria>
    <ADNode_1>2</ADNode_1>
    <CDNode_1>2</CDNode_1>
    <IFNode_1>0</IFNode_1>
    <ADNode_2>2</ADNode_2>
    <CDNode_2>0</CDNode_2>
    <IFNode_2>0</IFNode_2>
    <ADNode_3>0</ADNode_3>
    <CDNode_3>0</CDNode_3>
    <IFNode_3>0</IFNode_3>
  </Criteria>
  <session id="1056134770841202228344907">
    <Htd ID="21170">
      <Data_1>
        <Info Count="2"></Info>
        <Data Id="iV29308/B2/R1">
          <Type>TR1</Type>
        </Data>
        <Data Id="iV29308/B3/R1">
          <Type>TR1</Type>
        </Data>
        <Data Id="iV29308/B4/R1">
          <Type>TR1</Type>
        </Data>
        <Data Id="iV29308/B6/R1">
          <Type>TR1</Type>
        </Data>
      </Data_1>
      <Data_2>
        <Info Count="2"></Info>
        <Data Id="iV29308/B2/R1">
          <Type>TR2</Type>
        </Data>
        <Data Id="iV29308/B3/R1">
          <Type>TR2</Type>
        </Data>
        <Data Id="iV29308/B4/R1">
          <Type>TR2</Type>
        </Data>
        <Data Id="iV29308/B6/R1">
          <Type>TR3</Type>
        </Data>
      </Data_2>
    </Htd>
  </session>
</Ht>