我有一个需要阅读和编写的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>
我在这里创建了一个操场
答案 0 :(得分:0)
将条件和运算符插入到[] 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)
}