diff options
author | Brett Vickers <beevik@users.noreply.github.com> | 2019-11-04 21:02:52 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-04 21:02:52 -0800 |
commit | dcd53a58ac74b465a34228d599f14376ccdcc6ab (patch) | |
tree | 2b0732471da9af26c7e2a098b97f6fde61e55043 | |
parent | 6e5cd8a302168f3c32305811f9da1d4bd858be4c (diff) | |
download | go-etree-dcd53a58ac74b465a34228d599f14376ccdcc6ab.tar.gz |
Fix a bug in attribute namespaces. (#80)
Unprefixed attributes were being assigned an incorrect namespace URI.
See issue https://github.com/beevik/etree/issues/79
-rw-r--r-- | etree.go | 9 | ||||
-rw-r--r-- | etree_test.go | 73 |
2 files changed, 45 insertions, 37 deletions
@@ -1149,10 +1149,13 @@ func (a *Attr) Element() *Element { } // NamespaceURI returns the XML namespace URI associated with this attribute. -// The function returns the empty string if this attribute is part of the XML -// default namespace. +// The function returns the empty string if the attribute is unprefixed or +// if the attribute is part of the XML default namespace. func (a *Attr) NamespaceURI() string { - return a.element.NamespaceURI() + if a.Space == "" { + return "" + } + return a.element.findLocalNamespaceURI(a.Space) } // writeTo serializes the attribute to the writer. diff --git a/etree_test.go b/etree_test.go index 6288ec7..501f4ad 100644 --- a/etree_test.go +++ b/etree_test.go @@ -936,12 +936,12 @@ func TestAttrParent(t *testing.T) { func TestDefaultNamespaceURI(t *testing.T) { s := ` -<root xmlns="http://root.example.com" a="foo"> - <child1 xmlns="http://child.example.com" a="foo"> - <grandchild1 xmlns="http://grandchild.example.com" a="foo"> +<root xmlns="https://root.example.com" xmlns:attrib="https://attrib.example.com" attrib:a="foo" b="bar"> + <child1 xmlns="https://child.example.com" attrib:a="foo"> + <grandchild1 xmlns="https://grandchild.example.com" a="foo"> </grandchild1> <grandchild2 a="foo"> - <greatgrandchild1 a="foo"/> + <greatgrandchild1 attrib:a="foo"/> </grandchild2> </child1> <child2 a="foo"/> @@ -956,31 +956,36 @@ func TestDefaultNamespaceURI(t *testing.T) { greatgrandchild1 := grandchild2.SelectElement("greatgrandchild1") checkStrEq(t, doc.NamespaceURI(), "") - checkStrEq(t, root.NamespaceURI(), "http://root.example.com") - checkStrEq(t, child1.NamespaceURI(), "http://child.example.com") - checkStrEq(t, child2.NamespaceURI(), "http://root.example.com") - checkStrEq(t, grandchild1.NamespaceURI(), "http://grandchild.example.com") - checkStrEq(t, grandchild2.NamespaceURI(), "http://child.example.com") - checkStrEq(t, greatgrandchild1.NamespaceURI(), "http://child.example.com") - - checkStrEq(t, root.Attr[0].NamespaceURI(), "http://root.example.com") - checkStrEq(t, child1.Attr[0].NamespaceURI(), "http://child.example.com") - checkStrEq(t, child2.Attr[0].NamespaceURI(), "http://root.example.com") - checkStrEq(t, grandchild1.Attr[0].NamespaceURI(), "http://grandchild.example.com") - checkStrEq(t, grandchild2.Attr[0].NamespaceURI(), "http://child.example.com") - checkStrEq(t, greatgrandchild1.Attr[0].NamespaceURI(), "http://child.example.com") - - f := doc.FindElements("//*[namespace-uri()='http://root.example.com']") + checkStrEq(t, root.NamespaceURI(), "https://root.example.com") + checkStrEq(t, child1.NamespaceURI(), "https://child.example.com") + checkStrEq(t, child2.NamespaceURI(), "https://root.example.com") + checkStrEq(t, grandchild1.NamespaceURI(), "https://grandchild.example.com") + checkStrEq(t, grandchild2.NamespaceURI(), "https://child.example.com") + checkStrEq(t, greatgrandchild1.NamespaceURI(), "https://child.example.com") + + checkStrEq(t, root.Attr[0].NamespaceURI(), "") + checkStrEq(t, root.Attr[1].NamespaceURI(), "") + checkStrEq(t, root.Attr[2].NamespaceURI(), "https://attrib.example.com") + checkStrEq(t, root.Attr[3].NamespaceURI(), "") + checkStrEq(t, child1.Attr[0].NamespaceURI(), "") + checkStrEq(t, child1.Attr[1].NamespaceURI(), "https://attrib.example.com") + checkStrEq(t, child2.Attr[0].NamespaceURI(), "") + checkStrEq(t, grandchild1.Attr[0].NamespaceURI(), "") + checkStrEq(t, grandchild1.Attr[1].NamespaceURI(), "") + checkStrEq(t, grandchild2.Attr[0].NamespaceURI(), "") + checkStrEq(t, greatgrandchild1.Attr[0].NamespaceURI(), "https://attrib.example.com") + + f := doc.FindElements("//*[namespace-uri()='https://root.example.com']") if len(f) != 2 || f[0] != root || f[1] != child2 { t.Error("etree: failed namespace-uri test") } - f = doc.FindElements("//*[namespace-uri()='http://child.example.com']") + f = doc.FindElements("//*[namespace-uri()='https://child.example.com']") if len(f) != 3 || f[0] != child1 || f[1] != grandchild2 || f[2] != greatgrandchild1 { t.Error("etree: failed namespace-uri test") } - f = doc.FindElements("//*[namespace-uri()='http://grandchild.example.com']") + f = doc.FindElements("//*[namespace-uri()='https://grandchild.example.com']") if len(f) != 1 || f[0] != grandchild1 { t.Error("etree: failed namespace-uri test") } @@ -998,9 +1003,9 @@ func TestDefaultNamespaceURI(t *testing.T) { func TestLocalNamespaceURI(t *testing.T) { s := ` -<a:root xmlns:a="http://root.example.com"> - <b:child1 xmlns:b="http://child.example.com"> - <c:grandchild1 xmlns:c="http://grandchild.example.com"/> +<a:root xmlns:a="https://root.example.com"> + <b:child1 xmlns:b="https://child.example.com"> + <c:grandchild1 xmlns:c="https://grandchild.example.com"/> <b:grandchild2> <a:greatgrandchild1/> </b:grandchild2> @@ -1025,27 +1030,27 @@ func TestLocalNamespaceURI(t *testing.T) { greatgrandchild1 := grandchild2.SelectElement("greatgrandchild1") checkStrEq(t, doc.NamespaceURI(), "") - checkStrEq(t, root.NamespaceURI(), "http://root.example.com") - checkStrEq(t, child1.NamespaceURI(), "http://child.example.com") - checkStrEq(t, child2.NamespaceURI(), "http://root.example.com") + checkStrEq(t, root.NamespaceURI(), "https://root.example.com") + checkStrEq(t, child1.NamespaceURI(), "https://child.example.com") + checkStrEq(t, child2.NamespaceURI(), "https://root.example.com") checkStrEq(t, child3.NamespaceURI(), "") - checkStrEq(t, grandchild1.NamespaceURI(), "http://grandchild.example.com") - checkStrEq(t, grandchild2.NamespaceURI(), "http://child.example.com") - checkStrEq(t, grandchild3.NamespaceURI(), "http://root.example.com") + checkStrEq(t, grandchild1.NamespaceURI(), "https://grandchild.example.com") + checkStrEq(t, grandchild2.NamespaceURI(), "https://child.example.com") + checkStrEq(t, grandchild3.NamespaceURI(), "https://root.example.com") checkStrEq(t, grandchild4.NamespaceURI(), "") - checkStrEq(t, greatgrandchild1.NamespaceURI(), "http://root.example.com") + checkStrEq(t, greatgrandchild1.NamespaceURI(), "https://root.example.com") - f := doc.FindElements("//*[namespace-uri()='http://root.example.com']") + f := doc.FindElements("//*[namespace-uri()='https://root.example.com']") if len(f) != 4 || f[0] != root || f[1] != child2 || f[2] != grandchild3 || f[3] != greatgrandchild1 { t.Error("etree: failed namespace-uri test") } - f = doc.FindElements("//*[namespace-uri()='http://child.example.com']") + f = doc.FindElements("//*[namespace-uri()='https://child.example.com']") if len(f) != 2 || f[0] != child1 || f[1] != grandchild2 { t.Error("etree: failed namespace-uri test") } - f = doc.FindElements("//*[namespace-uri()='http://grandchild.example.com']") + f = doc.FindElements("//*[namespace-uri()='https://grandchild.example.com']") if len(f) != 1 || f[0] != grandchild1 { t.Error("etree: failed namespace-uri test") } |