xml - 如何使用 Unmarshal 解析 XML
问题描述
我在 Go 中编写了一个非常简单的 XML 解析器,但是我的 xml.Unmarshal 函数不能正常工作。这是示例代码。
我不确定我的结构是否正确。我读了一些页面,我认为这种格式更有条理。
package main
import (
"fmt"
"encoding/xml"
)
//this a xml sample of my document.
var str = `<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<mensagem>
<cabecalho>
<identificacaoTransacao>
<tipoTransacao>DESCRICAO</tipoTransacao>
<sequencialTransacao>5443811</sequencialTransacao>
<dataRegistroTransacao>2020-02-27</dataRegistroTransacao>
<horaRegistroTransacao>17:35:11</horaRegistroTransacao>
</identificacaoTransacao>
<origem>
<registroANS>005711</registroANS>
</origem>
<destino>
<identificacaoPrestador>
<codigoPrestadorNaOperadora>687146</codigoPrestadorNaOperadora>
</identificacaoPrestador>
</destino>
<Padrao>3.03.03</Padrao>
</cabecalho>
</mensagem>`
type XmlTISSIndex struct {
XMLCabecalho struct {
XMLAnsIdentificacaoTransacao struct {
XMLAnstipoTransacao string `xml:"tipoTransacao"`
XMLAnsSequenciaTransacao string `xml:"sequencialTransacao"`
XMLAnsDataRegistroTransacao string `xml:"dataRegistroTransacao"`
XMLAnsHoraRegistroTransacao string `xml:"horaRegistroTransacao"`
}
XMLAnsOrigem struct {
XMLAnsRegistro string `xml:"registroANS"`
}
XMLAnsDestino struct {
XMLAnsIdentificacaoPrestador struct {
XMLAnsCodigoPrestadorNaOperadora string `xml:"codigoPrestadorNaOperadora"`
}
}
}
}
func main() {
// variables
var data XmlTISSIndex
buffer := make([]byte,len(str))
buffer = []byte(str)
xml.Unmarshal(buffer,&data)
fmt.Print(data)
fmt.Println(data.XMLCabecalho.XMLAnsIdentificacaoTransacao.XMLAnsDataRegistroTransacao)
fmt.Println(data.XMLCabecalho.XMLAnsIdentificacaoTransacao.XMLAnsHoraRegistroTransacao)
fmt.Println(data.XMLCabecalho.XMLAnsIdentificacaoTransacao.XMLAnsSequenciaTransacao)
fmt.Println(data.XMLCabecalho.XMLAnsIdentificacaoTransacao.XMLAnstipoTransacao)
}
解决方案
您构建结构的方式不正确。此外,因为您使用的是 ISO-8859-1 编码,这让事情变得更加棘手......
我使用这篇文章来帮助解决这个问题。
像这样的东西应该工作:
package main
import (
"bytes"
"encoding/xml"
"fmt"
"golang.org/x/net/html/charset" // <-- Had to use this due to ISO-8859-1 encoding
)
// Sample document
var str = `<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<mensagem>
<cabecalho>
<identificacaoTransacao>
<tipoTransacao>DESCRICAO</tipoTransacao>
<sequencialTransacao>5443811</sequencialTransacao>
<dataRegistroTransacao>2020-02-27</dataRegistroTransacao>
<horaRegistroTransacao>17:35:11</horaRegistroTransacao>
</identificacaoTransacao>
<origem>
<registroANS>005711</registroANS>
</origem>
<destino>
<identificacaoPrestador>
<codigoPrestadorNaOperadora>687146</codigoPrestadorNaOperadora>
</identificacaoPrestador>
</destino>
<Padrao>3.03.03</Padrao>
</cabecalho>
</mensagem>`
type IdentificacaoTransacao struct {
XMLName xml.Name `xml:"identificacaoTransacao"`
TipoTransacao string `xml:"tipoTransacao"`
SequencialTransacao string `xml:"sequencialTransacao"`
DataRegistroTransacao string `xml:"dataRegistroTransacao"`
HoraRegistroTransacao string `xml:"horaRegistroTransacao"`
}
type Origem struct {
XMLName xml.Name `xml:"origem"`
RegistroANS string `xml:"registroANS"`
}
type IdentificacaoPrestador struct {
XMLName xml.Name `xml:"identificacaoPrestador"`
CodigoPrestadorNaOperadora string `xml:"codigoPrestadorNaOperadora"`
}
type Destino struct {
XMLName xml.Name `xml:"destino"`
IdentificacaoPrestador IdentificacaoPrestador `xml:"identificacaoPrestador"`
}
type Cabecalho struct {
XMLName xml.Name `xml:"cabecalho"`
IdentificacaoTransacao IdentificacaoTransacao `xml:"identificacaoTransacao"`
Origem Origem `xml:"origem"`
Destino Destino `xml:"destino"`
Padrao string `xml:"Padrao"`
}
type Mensagem struct {
XMLName xml.Name `xml:"mensagem"`
Cabecalho Cabecalho `xml:"cabecalho"`
}
func main() {
var mensagem Mensagem
var err error
byteStr := []byte(str)
reader := bytes.NewReader(byteStr)
decoder := xml.NewDecoder(reader)
decoder.CharsetReader = charset.NewReaderLabel
err = decoder.Decode(&mensagem)
if err != nil {
fmt.Println("Decoder error:", err)
}
fmt.Println(mensagem)
}
这给了我以下输出:
{{ mensagem} {{ cabecalho} {{ identificacaoTransacao} DESCRICAO 5443811 2020-02-27 17:35:11} {{ origem} 005711} {{ destino} {{ identificacaoPrestador} 687146}} 3.03.03}}
推荐阅读
- r - 将数据框中的列划分为另一个
- ruby-on-rails - 在 Rails 中用 NIL 覆盖路由参数?
- javascript - BootstrapVue 折叠并打开和关闭所有按钮
- python - 如何用asterix替换切片单词的其余部分?
- android - 实现导航库时出现 InflateException
- java - 在 MVP 设计模式中,Presenter 中的 View 使用 softReference 的目的是什么?
- java - 防止未经授权的成员加入 Hazelcast 集群
- keras - 如何在模型后期合并新特征?
- c++ - 用于 dmidecode 的 C/C++ API
- python-3.x - 有没有办法使用单个 for 循环来索引列表矩阵?