【问题标题】:Error unmarshalling GML with golang encoding/xml使用 golang 编码/xml 解组 GML 时出错
【发布时间】:2016-04-11 06:50:53
【问题描述】:

我正在尝试解组一些 XML,实际上是地理标记语言 (GML)。

我在http://play.golang.org/p/qS6GjCOtHF有一个例子

两个问题,第一个:

错误读取带有标签“boundedBy>Envelope>lowerCorner”的 xml main.FeatureCollection 字段“LowerCorner”与带有标签“boundedBy>Envelope”的字段“Envelope”冲突

我不知道如何解决这个问题。我将这些注释掉并让 GML 解组而没有错误,但是 FeatureCollection 中没有 Features

有什么线索吗?

GML 的一个例子是:

<?xml version="1.0" encoding="UTF-8"?>
<gml:FeatureCollection xmlns:gml="http://www.opengis.net/gml"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:fme="http://www.safe.com/gml/fme" xsi:schemaLocation="http://www.safe.com/gml/fme tblMainGML.xsd">
    <gml:boundedBy>
        <gml:Envelope srsName="EPSG:3112" srsDimension="2">
            <gml:lowerCorner>45.2921142578125 -80.2166748046875</gml:lowerCorner>
            <gml:upperCorner>169.000122070313 -9.14251708984375</gml:upperCorner>
        </gml:Envelope>
    </gml:boundedBy>
    <gml:featureMember>
        <fme:GML gml:id="id5255fa48-42b3-43d1-9e0d-b2ba8b57a936">
            <fme:OBJECTID>1</fme:OBJECTID>
            <fme:RECORD_ID>QLD48234</fme:RECORD_ID>
            <fme:NAME>HATCHMAN POINT</fme:NAME>
            <fme:FEAT_CODE>PT</fme:FEAT_CODE>
            <fme:CGDN>N</fme:CGDN>
            <fme:AUTHORITY_ID>QLD</fme:AUTHORITY_ID>
            <fme:CONCISE_GAZ>N</fme:CONCISE_GAZ>
            <fme:LATITUDE>-12.58361</fme:LATITUDE>
            <fme:lat_degrees>-12</fme:lat_degrees>
            <fme:lat_minutes>35</fme:lat_minutes>
            <fme:lat_seconds>0</fme:lat_seconds>
            <fme:LONGITUDE>141.62583</fme:LONGITUDE>
            <fme:long_degrees>141</fme:long_degrees>
            <fme:long_minutes>37</fme:long_minutes>
            <fme:long_seconds>32</fme:long_seconds>
            <fme:STATE_ID>QLD</fme:STATE_ID>
            <fme:STATUS>U</fme:STATUS>
            <fme:VARIANT_NAME />
            <fme:MAP_100K>7272</fme:MAP_100K>
            <fme:Place_ID>45880</fme:Place_ID>
            <gml:pointProperty>
                <gml:Point srsName="EPSG:3112" srsDimension="2">
                    <gml:pos>141.625915527344 -12.5836181640625</gml:pos>
                </gml:Point>
            </gml:pointProperty>
        </fme:GML>
    </gml:featureMember>
</gml:FeatureCollection>
</xml>

我的结构

type FeatureCollection struct {
    Xsi            string   `xml:"xsi,attr"`
    Fme            string   `xml:"fme,attr"`
    Gml            string   `xml:"gml,attr"`
    Xlink          string   `xml:"xlink,attr"`
    LowerCorner    string   `xml:"boundedBy>Envelope>lowerCorner"`
    UpperCorner    string   `xml:"boundedBy>Envelope>upperCorner"`
    Envelope       Envelope `xml:"boundedBy>Envelope"`
    SchemaLocation string   `xml:"schemaLocation,attr"`
    Features       []Feature
}

type Feature struct {
    PlaceID     string `xml:"featureMember>GML>Place_ID"`
    StateID     string `xml:"featureMember>GML>STATE_ID"`
    Postcode    string `xml:"featureMember>GML>POSTCODE"`
    CGDN        string `xml:"featureMember>GML>CGDN"`
    Map100K     string `xml:"featureMember>GML>MAP_100K"`
ETC...
}

【问题讨论】:

    标签: xml go unmarshalling gml-geographic-markup-lan xml-encoding


    【解决方案1】:

    一个 XML 标签只能映射到(最多)一个结构字段。 encoding/xml 包必须为每个 XML 标记决定它将被解码到哪个结构字段中。您对 XML 建模的结构很奇怪,并且使这个决定模棱两可。

    举个例子吧:

    type FeatureCollection struct {
        ...
        LowerCorner    string   `xml:"boundedBy>Envelope>lowerCorner"`
        UpperCorner    string   `xml:"boundedBy>Envelope>upperCorner"`
        Envelope       Envelope `xml:"boundedBy>Envelope"`
        ...
    }
    

    encoding/xml 包不能决定 XML 标签&lt;Envelope&gt; 应该被解码到哪里,例如进入LowerCorner?进入UpperCorner?进入Envelope?是的,我知道LowerCorner 只是&lt;Envelope&gt; 的一个子元素,但是由于整个&lt;Envelope&gt; 元素都映射到FeatureCollection.Envelope,所以这是不允许的。

    您应该将 LowerCornerUpperCorner 字段移动到您的 Envelope 结构类型中,因为这是它们所属的位置,并且您想要解组整个 Envelope xml 标记(或者如果没有,可以删除 FeatureCollection.Envelope完全)。因此,请按照此模式将字段放在它们所属的位置。

    这是您更新后的模型,它提取了您想要的所有信息:

    type FeatureCollection struct {
        Xsi            string   `xml:"xsi,attr"`
        Fme            string   `xml:"fme,attr"`
        Gml            string   `xml:"gml,attr"`
        Xlink          string   `xml:"xlink,attr"`
        Envelope       Envelope `xml:"boundedBy>Envelope"`
        SchemaLocation string   `xml:"schemaLocation,attr"`
        FeaturesGML    []GML    `xml:"featureMember>GML"`
    }
    type Envelope struct {
        SrsName      string `xml:"srsName,attr"`
        SrsDimension string `xml:"srsDimension,attr"`
        LowerCorner  string `xml:"lowerCorner"`
        UpperCorner  string `xml:"upperCorner"`
    }
    type GML struct {
        ID          string `xml:"id,attr"`
        PlaceID     string `xml:"Place_ID"`
        StateID     string `xml:"STATE_ID"`
        Postcode    string `xml:"POSTCODE"`
        CGDN        string `xml:"CGDN"`
        Map100K     string `xml:"MAP_100K"`
        Point       Point  `xml:"pointProperty>Point"`
        VariantName string `xml:"VARIANT_NAME"`
        RecordID    string `xml:"RECORD_ID"`
        LatSeconds  string `xml:"lat_seconds"`
        Status      string `xml:"STATUS"`
        LongSeconds string `xml:"long_seconds"`
        ConciseGAZ  string `xml:"CONCISE_GAZ"`
        Lattitude   string `xml:"LATITUDE"`
        AuthorityID string `xml:"AUTHORITY_ID"`
        Longitude   string `xml:"LONGITUDE"`
        LongMinutes string `xml:"long_minutes"`
        LatDegrees  string `xml:"lat_degrees"`
        NAME        string `xml:"NAME"`
        LatMinutes  string `xml:"lat_minutes"`
        ObjectID    string `xml:"OBJECTID"`
        FeatCode    string `xml:"FEAT_CODE"`
        LongDegrees string `xml:"long_degrees"`
    }
    type Point struct {
        SrsName      string `xml:"srsName,attr"`
        SrsDimension string `xml:"srsDimension,attr"`
        Pos          string `xml:"pos"`
    }
    

    这是您在 Go Playground 上的代码的修改版本,它运行时没有错误。

    验证您的结构是否包含来自 XML 的所有未编组信息:

    fmt.Printf("%+v", v)
    

    输出:

    &{的xsi:http://www.w3.org/2001/XMLSchema-instance FME:http://www.safe.com/gml/fme GML:http://www.opengis.net/gml的xlink:http://www.w3.org/1999/xlink信封:{SrsName:EPSG:3112 SrsDimension:2 LowerCorner:45.2921142578125 -80.2166748046875 UpperCorner:169.000122070313 -9.14251708984375} SCHEMALOCATION:http://www.safe.com/gml/fme tblmaingml.xsd功能:[{id:id5255fa48-42b3-43d1-920d-b2ba8b57a936 placeId:45880 stateId:qld邮政编码:cgdn:n map100k:7272点:{srsname:epsg:3112 srsdimension:2 pos:141.625915527344 -12.5836181640625变量名称:RecordID:QLD48234 LatSeconds:0 状态:U LongSeconds:32 ConciseGAZ:N 纬度:-12.58361 AuthorityID:QLD 经度:141.62583 LongMinutes:37 LatDegrees:-12 NAME:HATCHMAN POINT LatMinutes:35 ObjectID:1 FeatCode:PT LongDegrees: 141}]}

    【讨论】:

    • 谢谢,我可能应该提到原始标记来自使用 github.com/wicast/xj2s。我更改了该工具提出的平面结构,但显然弄错了。我认为标签有点冗长。现在一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    相关资源
    最近更新 更多