# HG changeset patch # User Sascha L. Teichmann # Date 1545048118 -3600 # Node ID e80e35b26f1721a28c18e0f8068e2e444e366cce # Parent b88cc5aadcc1475bacb006ac0fc793e82f687d31 WFS Capabilities parser: Wrote a custom xml.Unmarshaler to extract the namespaces of FeatureTypes, too. They are needed in GetFeature requests. diff -r b88cc5aadcc1 -r e80e35b26f17 cmd/wfs/main.go --- a/cmd/wfs/main.go Mon Dec 17 12:31:56 2018 +0100 +++ b/cmd/wfs/main.go Mon Dec 17 13:01:58 2018 +0100 @@ -44,7 +44,13 @@ fmt.Println("service identification") fmt.Println("----------------------") fmt.Printf("title: %s\n", caps.ServiceIdentification.Title) - fmt.Printf("abstract: %s\n", caps.ServiceIdentification.Abstract) + var abstract string + if len(caps.ServiceIdentification.Abstract) > 40 { + abstract = fmt.Sprintf("%.40s...", caps.ServiceIdentification.Abstract) + } else { + abstract = caps.ServiceIdentification.Abstract + } + fmt.Printf("abstract: %s\n", abstract) if len(caps.ServiceIdentification.Keywords.Keywords) > 0 { fmt.Println("keywords:") for _, kw := range caps.ServiceIdentification.Keywords.Keywords { @@ -116,6 +122,13 @@ for _, ft := range caps.FeatureTypeList.FeatureTypes { fmt.Printf("\tname: %s\n", ft.Name) fmt.Printf("\ttitle: %s\n", ft.Title) + var abstract string + if len(ft.Abstract) > 40 { + abstract = fmt.Sprintf("%.40s...", ft.Abstract) + } else { + abstract = ft.Abstract + } + fmt.Printf("\tabstract: %s\n", abstract) fmt.Printf("\tdefault CRS: %s\n", ft.DefaultCRS) if len(ft.OtherCRSs) > 0 { fmt.Println("\tother CRSs:") @@ -128,11 +141,17 @@ ft.WGS84BoundingBox.LowerCorner, ft.WGS84BoundingBox.UpperCorner) } if len(ft.Keywords.Keywords) > 0 { - fmt.Printf("\tkeywords:\n") + fmt.Println("\tkeywords:") for _, kw := range ft.Keywords.Keywords { fmt.Printf("\t\t%s\n", kw.Value) } } + if len(ft.Namespaces) > 0 { + fmt.Println("\tnamespaces:") + for _, ns := range ft.Namespaces { + fmt.Printf("\t\t%s:%s\n", ns.Space, ns.Local) + } + } } } } diff -r b88cc5aadcc1 -r e80e35b26f17 pkg/wfs/capabilities.go --- a/pkg/wfs/capabilities.go Mon Dec 17 12:31:56 2018 +0100 +++ b/pkg/wfs/capabilities.go Mon Dec 17 13:01:58 2018 +0100 @@ -111,10 +111,42 @@ XMLName xml.Name `xml:"http://www.opengis.net/wfs/2.0 FeatureType"` Name string `xml:"Name"` Title string `xml:"Title"` + Abstract string `xml:"Abstract"` + Keywords Keywords `xml:"Keywords"` + DefaultCRS string `xml:"DefaultCRS"` + OtherCRSs []string `xml:"OtherCRS"` + WGS84BoundingBox *WGS84BoundingBox `xml:"WGS84BoundingBox"` + Namespaces []xml.Name `xml:"-"` +} + +// shadowFeatureType is used to prevent recursive UnmarshalXML for FeatureType. +type shadowFeatureType struct { + XMLName xml.Name `xml:"http://www.opengis.net/wfs/2.0 FeatureType"` + Name string `xml:"Name"` + Title string `xml:"Title"` + Abstract string `xml:"Abstract"` Keywords Keywords `xml:"Keywords"` DefaultCRS string `xml:"DefaultCRS"` OtherCRSs []string `xml:"OtherCRS"` WGS84BoundingBox *WGS84BoundingBox `xml:"WGS84BoundingBox"` + Namespaces []xml.Name `xml:"-"` +} + +func (ft *FeatureType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + // Filter out the namespaces for this feature type. + var ns []xml.Name + for _, attr := range start.Attr { + if attr.Name.Space == "xmlns" { + ns = append(ns, xml.Name{Space: attr.Name.Local, Local: attr.Value}) + } + } + var sft shadowFeatureType + if err := d.DecodeElement(&sft, &start); err != nil { + return err + } + *ft = FeatureType(sft) + ft.Namespaces = ns + return nil } type FeatureTypeList struct {