如何正确解析xml

时间:2016-02-03 13:54:33

标签: xml go epp

我想创建结构=每种类型的命令。

命令具有xml的共同部分 - CommandResult。我创建了接口命令。我需要SomeCommand实现Command并且可以解析为xml,同样必须在CommandResult中实现IsError,其他函数必须由SomeCommand实现。

代码:

type Command interface {
    IsError() bool

    Request(buf *bufio.Writer, params interface{}) error
    ...
}

// Result of request
type CommandResult struct {
    Code    int    `xml:"code,attr" json:"code"`
    Message string `xml:"msg" json:"msg"`
}

// this Command's func is realized by CommandResult 
func (self CommandResult) IsError() bool {
    return true
}


// some command
type SomeCommand struct {
    CommandResult // CommandResult `xml:"response>result" json:"result"`
}

// this Command's func is realized by SomeCommand 
func (self SomeCommand) Request(buf *bufio.Writer, params interface{}) error {
    return nil
}

// other Command's functions are realized by CommandResult too

XML:

<epp>
  <response>
    <result code="1000">
      <msg>Command completed successfully</msg>
    </result>
    <trID>
      <svTRID>asd</svTRID>
    </trID>
  </response>
</epp>

预期结果:

a := SomeCommand
xml.NewDecoder(reader).Decode(&a)
// a.CommandResult.Code = 1000
// a.CommandResult.Message = 'Command completed successfully'

// a implements Command

1 个答案:

答案 0 :(得分:1)

  1. 我认为嵌入式结构中的路径应该是绝对的,因为父母的所有路径都是&#34;结构是孩子的一部分&#34;。所以你的

     type CommandResult struct {
         Code    int    `xml:"code,attr" json:"code"`
         Message string `xml:"msg" json:"msg"`
     }
    

    应该更像

     type CommandResult struct {
         Code    int    `xml:"response>result>code,attr" json:"code"`
         Message string `xml:"response>result>msg" json:"msg"`
     }
    

    BUT!在那里,我们面临着Go的限制。

  2. 您不能将attr与链接一起使用。有issue on Github但看起来它不在优先级列表中。因此,如果我理解您的CommandResult声明的最短版本将是:

    type CommandResult struct {
        Result struct {
            Code    int    `xml:"code,attr" json:"code"`
            Message string `xml:"msg" json:"msg"`
        } `xml:"response>result" json:"response"`
    }
    
  3. 这不是一个真正的问题,但如果你决定将Command转换回XML,那么宣告它的XMLName会很好。像

    这样的东西
    type CommandResult struct {
        XMLName xml.Name `xml:"epp"`
        Result  struct {
            Code    int    `xml:"code,attr" json:"code"`
            Message string `xml:"msg" json:"msg"`
        } `xml:"response>result" json:"response"`
    }
    

    因为没有它,XML编码器会产生类似<SomeCommand><response>...</response></SomeCommand>

  4. 的东西

    使用完整示例进行更新

    package main
    
    import (
        "bufio"
        "encoding/xml"
        "log"
    )
    
    type Command interface {
        IsError() bool
    
        Request(buf *bufio.Writer, params interface{}) error
    }
    
    // Result of request
    type CommandResult struct {
        XMLName xml.Name `xml:"epp"`
        Result  struct {
            Code    int    `xml:"code,attr" json:"code"`
            Message string `xml:"msg" json:"msg"`
        } `xml:"response>result" json:"response"`
    }
    
    // this Command's func is realized by CommandResult
    func (self CommandResult) IsError() bool {
        return true
    }
    
    // some command
    type SomeCommand struct {
        CommandResult
    }
    
    // this Command's func is realized by SomeCommand
    func (self SomeCommand) Request(buf *bufio.Writer, params interface{}) error {
        return nil
    }
    
    type AnotherCommand struct {
        CommandResult
    }
    
    func (self AnotherCommand) Request(buf *bufio.Writer, params interface{}) error {
        return nil
    }
    
    func main() {
        var c Command
    
        c = SomeCommand{}
        log.Println(c.IsError())
    
        c = AnotherCommand{}
        log.Println(c.IsError())
    }