Skip to content

Commit

Permalink
Fixing xml bug
Browse files Browse the repository at this point in the history
  • Loading branch information
xibz committed Dec 2, 2016
1 parent c90e387 commit 9559dd1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
7 changes: 2 additions & 5 deletions private/protocol/xml/xmlutil/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,8 @@ func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
elems := node.Children[name]

if elems == nil { // try to find the field in attributes
for _, a := range node.Attr {
if name == strings.Join([]string{a.Name.Space, a.Name.Local}, ":") {
// turn this into a text node for de-serializing
elems = []*XMLNode{{Text: a.Value}}
}
if val, ok := node.findElem(name); ok {
elems = []*XMLNode{{Text: val}}
}
}

Expand Down
39 changes: 27 additions & 12 deletions private/protocol/xml/xmlutil/xml_to_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/xml"
"io"
"sort"
"strings"
)

// A XMLNode contains the values to be encoded or decoded.
Expand All @@ -12,6 +13,9 @@ type XMLNode struct {
Children map[string][]*XMLNode `json:",omitempty"`
Text string `json:",omitempty"`
Attr []xml.Attr `json:",omitempty"`

namespaces map[string]string
parent *XMLNode
}

// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
Expand Down Expand Up @@ -59,41 +63,52 @@ func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
slice = []*XMLNode{}
}
node, e := XMLToStruct(d, &el)
out.findNamespaces()
if e != nil {
return out, e
}
node.Name = typed.Name
node.Attr = out.Attr
node = adaptNode(node)
node.findNamespaces()
tempOut := *out
// Save into a temp variable, simply because out gets squashed during
// loop iterations
node.parent = &tempOut
slice = append(slice, node)
out.Children[name] = slice
case xml.EndElement:
if s != nil && s.Name.Local == typed.Name.Local { // matching end token
return out, nil
}
out = &XMLNode{}
}
}
return out, nil
}

func adaptNode(node *XMLNode) *XMLNode {
func (n *XMLNode) findNamespaces() {
ns := map[string]string{}
for _, a := range node.Attr {
for _, a := range n.Attr {
if a.Name.Space == "xmlns" {
ns[a.Value] = a.Name.Local
break
}
}

for i, a := range node.Attr {
if a.Name.Space == "xmlns" {
continue
}
if v, ok := ns[node.Attr[i].Name.Space]; ok {
node.Attr[i].Name.Space = v
n.namespaces = ns
}

func (n *XMLNode) findElem(name string) (string, bool) {
for node := n; node != nil; node = node.parent {
for _, a := range node.Attr {
namespace := a.Name.Space
if v, ok := node.namespaces[namespace]; ok {
namespace = v
}
if name == strings.Join([]string{namespace, a.Name.Local}, ":") {
return a.Value, true
}
}
}
return node
return "", false
}

// StructToXML writes an XMLNode to a xml.Encoder as tokens.
Expand Down

0 comments on commit 9559dd1

Please sign in to comment.