我有一个需要阅读和编写的XML片段。这是一个<condition>数组,除最后一个实体外,每个数组之间都有一个<operator>

<conditions>
    <condition>
      <label>a</label>
    </condition>
    <operator>AND</operator>
    <condition>
      <label>b</label>
    </condition>
    <operator>AND</operator>
    <condition>
      <label>c</label>
    </condition>
<conditions>

我的Go模型看起来像这样
type Condition struct {
    XMLName xml.Name `xml:"condition" json:"-"`
    Label   string   `xml:"label"`
}

type Conditions struct {
    ConditionList []Condition `xml:"condition,omitempty"`
    Operator      string      `xml:"operator"`
}

如果我编组该结构,则操作员仅在底部出现一次。符合预期
<Conditions>
  <condition>
    <label>a</label>
  </condition>
  <condition>
    <label>b</label>
  </condition>
  <condition>
    <label>c</label>
  </condition>
  <operator>AND</operator>
</Conditions>

如何使运算符出现在除最后一个条件之外的所有条件之后?

我能得到的最接近的是使用包装器
func (c Conditions) MarshalXML(e *xml.Encoder, start xml.StartElement) error {

    type tCondition struct {
        XMLName xml.Name `xml:"condition" json:"-"`
        Label   string   `xml:"label"`
    }
    type tConditionWithOp struct {
        XMLName   xml.Name   `xml:"-" json:"-"`
        Condition tCondition `xml: "conditions"`
        Operator  string     `xml:",omitempty"`
    }
    type tWrapper struct {
        OPS []tConditionWithOp
    }

    lst := make([]tConditionWithOp, 0, 10)

    for idx, cond := range c.ConditionList {
        tCond := tCondition{
            Label: cond.Label,
        }
        tCondOp := tConditionWithOp{
            Condition: tCond,
        }

        if idx < len(c.ConditionList)-1 {
            tCondOp.Operator = c.Operator
        }

        lst = append(lst, tCondOp)

    }
    wrapper := tWrapper{
        OPS: lst,
    }

    return e.EncodeElement(wrapper, start)
}

但是我现在有一个<OPS>标签
<Conditions>
  <OPS>
    <condition>
      <label>a</label>
    </condition>
    <Operator>AND</Operator>
  </OPS>
  <OPS>
    <condition>
      <label>b</label>
    </condition>
    <Operator>AND</Operator>
  </OPS>
  <OPS>
    <condition>
      <label>c</label>
    </condition>
  </OPS>
</Conditions>

我在这里建立了一个游乐场

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

最佳答案

将条件和运算符插入到[] interface {}数组中即可。谢谢

type Operator struct {
    Name string
}

func (op Operator) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
    start.Name.Local = "operator"
    return e.EncodeElement(op.Name, start)
}

func (c Conditions) MarshalXML(e *xml.Encoder, start xml.StartElement) error {

    start.Name.Local = "conditions"
    var arr []interface{}

    for idx, cond := range c.ConditionList {
        if idx > 0 {
            arr = append(arr, Operator{Name: c.Operator})
        }
        arr = append(arr, cond)
    }

    type root struct {
        ARR []interface{}
    }

    return e.EncodeElement(root{ARR: arr}, start)
}

关于xml - 数组之间使用字符串的自定义XML编码(marshal),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55048221/

10-16 23:19