我有一段需要读写的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>
我在这里创建了一个游乐场
将交叉条件和运算符元素放入[] 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)
}