restoreAttrNamespaces update XML attributes to restore the short namespaces found within the raw XML document.
(node xml.StartElement)
| 49 | // restoreAttrNamespaces update XML attributes to restore the short namespaces found within |
| 50 | // the raw XML document. |
| 51 | func restoreAttrNamespaces(node xml.StartElement) xml.StartElement { |
| 52 | if len(node.Attr) == 0 { |
| 53 | return node |
| 54 | } |
| 55 | |
| 56 | // Generate a mapping of XML namespace values to their short names. |
| 57 | ns := map[string]string{} |
| 58 | for _, a := range node.Attr { |
| 59 | if a.Name.Space == "xmlns" { |
| 60 | ns[a.Value] = a.Name.Local |
| 61 | break |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | for i, a := range node.Attr { |
| 66 | if a.Name.Space == "xmlns" { |
| 67 | continue |
| 68 | } |
| 69 | // By default, xml.Decoder will fully resolve these namespaces. So if you had <foo xmlns:bar=baz bar:bin=hi/> |
| 70 | // then by default the second attribute would have the `Name.Space` resolved to `baz`. But we need it to |
| 71 | // continue to resolve as `bar` so we can easily identify it later on. |
| 72 | if v, ok := ns[node.Attr[i].Name.Space]; ok { |
| 73 | node.Attr[i].Name.Space = v |
| 74 | } |
| 75 | } |
| 76 | return node |
| 77 | } |
| 78 | |
| 79 | // GetElement looks for the given tag name at the current level, and returns the element if found, and |
| 80 | // skipping over non-matching elements. Returns an error if the node is not found, or if an error occurs while walking |