4

GoでXMLの場合、私はピースを解析しようとしています:

package main

import (
    "encoding/xml"
    "fmt"
)

type XML struct {
    Foo string `xml:"foo"`
}

func main() {
    rawXML := []byte(`
<xml>
  <foo>A</foo>
  <ns:foo>B</ns:foo>
</xml>`)

    x := new(XML)
    xml.Unmarshal(rawXML, x)
    fmt.Printf("foo: %s\n", x.Foo)
}

これは以下を出力します:

foo: B

私はそれが生成することを期待していましたが:

foo: A

foo最初のタグ (つまり、名前空間のないもの)のコンテンツを取得するにはどうすればよいですか?

4

3 に答える 3

8

xml デコーダーが、構造体タグを含む名前空間を持たない要素を指定できるとは思いません。ただし、名前空間に関する情報を取得できることは知っています。その後、データを後処理して同じ結果を得ることができます。

package main

import (
    "encoding/xml"
    "fmt"
)

type Foo struct {
    XMLName xml.Name
    Data string `xml:",chardata"`
}

type XML struct {
    Foo []Foo `xml:"foo"`
}

func main() {
    rawXML := []byte(`
<xml>
  <foo>A</foo>
  <ns:foo>B</ns:foo>
</xml>`)

    x := new(XML)
    xml.Unmarshal(rawXML, x)
    //fmt.Printf("foo: %#v\n", x)
    for _, el := range x.Foo {
       if el.XMLName.Space == "" {
          fmt.Printf("non namespaced foo %q", el.Data)
      }
    }
}

http://play.golang.org/p/aDEFPmHPc0

于 2013-01-04T07:18:45.790 に答える
4

xml ドキュメントに連続する 2 つの値があります。構造体には 1 つの値しか入れられません。xml パーサーは最初のものを解析してから、2 番目のもので上書きしています。

Foo を構造体のスライスに変更すると、両方の値が得られます。

http://play.golang.org/p/BRgsuMQ7rK

package main

import (
    "encoding/xml"
    "fmt"
)

type XML struct {
    Foo []string `xml:"foo"`
}

func main() {
    rawXML := []byte(`
<xml>
  <foo>A</foo>
  <ns:foo>B</ns:foo>
</xml>`)

    x := new(XML)
    xml.Unmarshal(rawXML, x)
    fmt.Printf("foo: %s\n", x.Foo[0])
    fmt.Printf("both: %v\n", x.Foo)
}
于 2013-01-03T19:44:44.720 に答える
0

xml:"foo"セレクター構文はオプションの namespace を取りますがxml:"ns foo"、問題は、名前空間なしで選択する方法をサポートしていないことです。

解決策の 1 つは、名前空間を名前空間のないタグに割り当てるだけで、次の構文xml.Decoder.DefaultSpaceを使用して選択できるようになりました。xml:"<ns> <tag>"

https://play.golang.org/p/1UggvqLFT9x

import (
    "encoding/xml"
    "strings"
    "fmt"
)

type Doc struct {
    Foo string `xml:"_ foo"` // <-- <foo> will now be <_:foo>
    NsFoo string `xml:"ns foo"`
}

var input = `<xml>
  <foo>A</foo>
  <ns:foo>B</ns:foo>
</xml>`

func main() {
    decoder := xml.NewDecoder(strings.NewReader(input))
    decoder.DefaultSpace = "_"

    doc := &Doc{}
    decoder.Decode(doc)

    fmt.Printf("<foo>: %#v\n", doc.Foo)
    fmt.Printf("<ns:foo>: %#v\n", doc.NsFoo)

}

版画:

<foo>: A
<ns:foo>: B
于 2020-06-11T06:21:32.700 に答える