繁体   English   中英

解组多个XML项

[英]Unmarshal multiple XML items

我试图解组具有相同结构的节点中包含的多个项目,以进行进一步处理,但似乎无法访问数据,我不确定为什么。 XML数据的结构形式如下(我正在尝试访问所有Item

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<datainfo>
  <origin>NOAA/NOS/CO-OPS</origin>
  <producttype> Annual Tide Prediction </producttype>
  <IntervalType>High/Low Tide Predictions</IntervalType>
  <data>
    <item>
      <date>2015/12/31</date>
      <day>Thu</day>
      <time>03:21 AM</time>
      <predictions_in_ft>5.3</predictions_in_ft>
      <predictions_in_cm>162</predictions_in_cm>
      <highlow>H</highlow>
    </item>
    <item>
      <date>2015/12/31</date>
      <day>Thu</day>
      <time>09:24 AM</time>
      <predictions_in_ft>2.4</predictions_in_ft>
      <predictions_in_cm>73</predictions_in_cm>
      <highlow>L</highlow>
    </item>
  </data>
</datainfo>

我的代码是:

package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

// TideData stores a series of tide predictions
type TideData struct {
    Tides []Tide `xml:"data>item"`
}

// Tide stores a single tide prediction
type Tide struct {
    Date         string  `xml:"date"`
    Day          string  `xml:"day"`
    Time         string  `xml:"time"`
    PredictionFt float64 `xml:"predictions_in_ft"`
    PredictionCm float64 `xml:"predictions_in_cm"`
    HighLow      string  `xml:"highlow"`
}

func (t Tide) String() string {
    return t.Date + " " + t.Day + " " + t.Time + " " + t.HighLow
}

func main() {
    xmlFile, err := os.Open("9414275 Annual.xml")
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer xmlFile.Close()

    b, _ := ioutil.ReadAll(xmlFile)

    var tides TideData
    xml.Unmarshal(b, &tides)

    fmt.Println(tides)
    for _, datum := range tides.Tides {
        fmt.Printf("\t%s\n", datum)
    }
}

运行时,输出为空,这使我认为数据不是未整理的。 输出为:

{[]}

您将忽略xml.Unmarshal的错误返回。 通过稍微修改您的程序 ,我们可以看到发生了什么:

xml: encoding "ISO-8859-1" declared but Decoder.CharsetReader is nil

翻阅文档 ,我们发现默认情况下该包仅支持以UTF-8编码的XML:

    // CharsetReader, if non-nil, defines a function to generate
    // charset-conversion readers, converting from the provided
    // non-UTF-8 charset into UTF-8. If CharsetReader is nil or
    // returns an error, parsing stops with an error. One of the
    // the CharsetReader's result values must be non-nil.
    CharsetReader func(charset string, input io.Reader) (io.Reader, error)

因此,似乎您需要提供自己的字符集转换例程。 您可以通过如下修改代码来注入它:

decoder := xml.NewDecoder(xmlFile)
decoder.CharsetReader = makeCharsetReader
err := decoder.Decode(&tides)

(请注意,我们现在正在从io.Reader而不是字节数组进行解码,因此可以删除ReadAll逻辑)。 golang.org/x/text/encoding包的家庭可能会帮助您实施makeCharsetReader功能。 这样的事情可能会起作用:

import "golang.org/x/text/encoding/charmap"

func makeCharsetReader(charset string, input io.Reader) (io.Reader, error) {
    if charset == "ISO-8859-1" {
        // Windows-1252 is a superset of ISO-8859-1, so should do here
        return charmap.Windows1252.NewDecoder().Reader(input), nil
    }
    return nil, fmt.Errorf("Unknown charset: %s", charset)
}

然后,您应该能够解码XML。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM