dongpo2340 2019-03-19 17:37
浏览 5
已采纳

解组时是否可以合并没有专用根元素的XML子节点?

I have an XML structure to work with were a part looks like

   <Rights>
      <Name>NAS</Name>
      <Access>2</Access>
      <Name>App</Name>
      <Access>1</Access>
   </Rights>

This is (obviously) a list, and it is guaranteed that it contains of pairs Name, Access (and always in that particular order). My question: Can I use the encoding/xml package's Unmarshal function to unmarshal Name and Access in a single struct?

Consider the following example:

package main

import (
    "encoding/xml"
    "fmt"
)

var XML = []string{`
?xml version="1.0" encoding="UTF-8"?>
<SessionInfo>
   <SID>abc123</SID>
   <Rights>
      <Name>NAS</Name>
      <Access>2</Access>
      <Name>App</Name>
      <Access>1</Access>
   </Rights>
</SessionInfo>
`,`
<SessionInfo>
   <SID>def456</SID>
   <Rights />
</SessionInfo>
`}

type Right struct {
    Name string
    Access int
}

type SessionInfo struct {
    XMLName   xml.Name `xml:"SessionInfo"`
    SID       string
    Rights    []Right
}

func main() {
    for _,entry := range XML {
        info := SessionInfo{}
        if err := xml.Unmarshal([]byte(entry), &info); err != nil {
            fmt.Println("Marshal failed", err.Error())
            continue
        }
        fmt.Printf("%+v
", info)
    }
}

This doesn't work as expected:

// Only the first value is found
{SID:abc123 Rights:[{Name:App Access:1}]} 
// One (not existing) value was found and the struct's zero value was used
{SID:def456 Rights:[{Name: Access:0}]}

I could (and this works) define the properties independent of each other like

Names []string `xml:"Rights>Name"`
Accesses []int `xml:"Rights>Access"`

But I'd prefer the structure format of the first version without converting them manually.

Is there a way to get the expected result?

  • 写回答

1条回答 默认 最新

  • duanbimo7212 2019-03-27 14:09
    关注

    I'm using XPath library xmlquery not Go marshal/unmash method.

    package main
    
    import (
        "fmt"
        "strings"
    
        "github.com/antchfx/xmlquery"
    )
    
    func main() {
        s := `
    ?xml version="1.0" encoding="UTF-8"?>
    <SessionInfo>
       <SID>abc123</SID>
       <Rights>
          <Name>NAS</Name>
          <Access>2</Access>
          <Name>App</Name>
          <Access>1</Access>
       </Rights>
    </SessionInfo>
    `
        doc, err := xmlquery.Parse(strings.NewReader(s))
        if err != nil {
            panic(err)
        }
        for _, elem := range xmlquery.Find(doc, "//SessionInfo") {
            sid := xmlquery.FindOne(elem, "SID")
            fmt.Printf("sid: %s
    ", sid.InnerText())
            for _, name := range xmlquery.Find(elem, "Rights/Name") {
                fmt.Printf("name: %s
    ", name.InnerText())
            }
        }
    }
    
    

    output

    sid: abc123
    name: NAS
    name: App
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 GD32 SPI通信时我从机原样返回收到的数据怎么弄?
  • ¥15 phython读取excel表格报错 ^7个 SyntaxError: invalid syntax 语句报错
  • ¥20 @microsoft/fetch-event-source 流式响应问题
  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?