Go 中的 XML 解组给出带有导出字段的空结果

问题描述 投票:0回答:2

在 Go 中进行 XML 解组时得到空结果。我研究了其他 SO 问题,我注意到最常见的原因似乎是这些字段未导出。在我的例子中情况并非如此,因为所有名称都以大写字母开头。

xml 看起来像这样(在一个

ROW
内有近 1.000.000 个
ROWDATA
标签):

<ROWDATA>
<ROW>
  <ПІБ>    ПОПКО    РУСЛАН ВАСИЛЬОВИЧ</ПІБ>
  <Місце_проживання>61112, Харківська обл., місто Харків, Московський район, ПРОСПЕКТ П'ЯТДЕСЯТИРІЧЧЯ ВЛКСМ, будинок 86, квартира 65</Місце_проживання>
  <Основний_вид_діяльності>45.32 Роздрібна торгівля деталями та приладдям для автотранспортних засобів</Основний_вид_діяльності>
  <Стан>зареєстровано</Стан>
</ROW>
</ROWDATA>

这就是我所做的:

package main
import (
    "encoding/xml"
    "fmt"
    "golang.org/x/text/encoding/charmap"
    "golang.org/x/text/transform"
    "io/ioutil"
    "os"
    "strings"
)

type Rowdata struct {
    XMLName xml.Name `xml:"ROWDATA"`
    Rowdata []Row    `xml:"ROW"`
}

type Row struct {
    XMLName  xml.Name `xml:"ROW"`
    Location string   `xml:"Місце_проживання"`
    Director string   `xml:"ПІБ"`
    Activity string   `xml:"Основний_вид_діяльності"`
    City     string   `xml:"Стан"`
}

func main() {

    xmlFile, err := os.Open("FOP_1.xml")
    if err != nil {
        fmt.Println(err)
    }

    defer xmlFile.Close()

    byteValue, _ := ioutil.ReadAll(xmlFile)

    koi8rString := transform.NewReader(strings.NewReader(string(byteValue)), charmap.Windows1251.NewDecoder())

    decBytes, _ := ioutil.ReadAll(koi8rString)

    var entries Rowdata

    xml.Unmarshal(decBytes, &entries)

    for i := 0; i < len(entries.Rowdata); i++ {
        fmt.Println("Name: " + entries.Rowdata[i].Director)
    }
}

最后一个 for 循环永远不会运行,因为长度为零。不过,我有一个类似的例子,文件已经是UTF8了,所以不需要编码转换,而且进展顺利。我想知道我解码时是否搞砸了什么?

更新:我使用字符串而不是Go Play Space中的文件测试了一个更简单的版本,并且效果很好!但是,我的本地版本的文件仍然无法工作,所以我怀疑它可能与文件的实际读取有关......

更新2:我刚刚意识到

xml.Unmarshall
返回:

xml: encoding "windows-1251" declared but Decoder.CharsetReader is nil%

这可能是原因......但这意味着什么?

xml go unmarshalling
2个回答
2
投票

您提到您有“近 1.000.000 个 ROW 标签”,并且在您的代码中使用

ioutil.ReadAll(xmlFile)
将其全部读入内存(两次!) - 这完全没有必要,您可能会耗尽内存。您应该使用“流式”解码器,而不是将其读入内存,例如

import "golang.org/x/net/html/charset"

func main() {
    xmlFile, err := os.Open("FOP_1.xml")
    if err != nil {
        fmt.Println(err)
    }
    defer xmlFile.Close()

    parser := xml.NewDecoder(xmlFile)
    parser.CharsetReader = charset.NewReaderLabel

    for {
        t, _ := parser.Token()
        if t == nil {
            break
        }

        switch se := t.(type) {
        case xml.StartElement:
            if se.Name.Local == "ROW" {
                var item Row
                parser.DecodeElement(&item, &se)
                fmt.Println("Name: " + item.Director)
            }
       }
    }
}

0
投票
import "golang.org/x/net/html/charset"

decoder := xml.NewDecoder(file)
decoder.CharsetReader = charset.NewReaderLabel

err := decoder.Decode(&temp)
if err != nil {
    return
}
© www.soinside.com 2019 - 2024. All rights reserved.