douhuang3740 2019-03-07 16:09
浏览 31

数组之间使用字符串的自定义XML元帅

I have a snippet of XML I need to read and write. It's an array of <condition> with an <operator> in between each except for the last entity.

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

My Go model looks like this

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"`                                                                                                                                                                                                                                            
}   

If I marshal the struct the operator only appears once on the bottom. as expected

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

How do i get the operator to appear after every condition except for the last one?

The closest i could get was using a wrapper

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)                                                                                                                                                                                                                                                
}  

But I now have an <OPS> tag

<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>

I have created a playground here

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

  • 写回答

1条回答 默认 最新

  • dsarttv037029 2019-03-08 12:45
    关注

    Interleaving conditions and operator elements into an []interface{} array worked. Thanks

    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)                                                                                                            
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类