Skip to content

Commit a86901e

Browse files
committed
fixed #96
1 parent a71e7cc commit a86901e

2 files changed

Lines changed: 67 additions & 11 deletions

File tree

parse.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,15 @@ func (p *parser) parse() (*Node, error) {
105105
p.prev = node
106106
}
107107
// https://www.w3.org/TR/xml-names/#scoping-defaulting
108-
var defaultNameSpace string
108+
var defaultNamespaceURL string
109109
for _, att := range tok.Attr {
110110
if att.Name.Local == "xmlns" {
111-
p.space2prefix[att.Value] = ""
112-
defaultNameSpace = att.Value
111+
p.space2prefix[att.Value] = "" // reset empty if exist the default namespace
112+
defaultNamespaceURL = att.Value
113113
} else if att.Name.Space == "xmlns" {
114-
p.space2prefix[att.Value] = att.Name.Local
114+
if _, ok := p.space2prefix[att.Value]; !ok {
115+
p.space2prefix[att.Value] = att.Name.Local
116+
}
115117
}
116118
}
117119

@@ -135,17 +137,13 @@ func (p *parser) parse() (*Node, error) {
135137
}
136138

137139
node := &Node{
138-
Type: ElementNode,
139-
Data: tok.Name.Local,
140-
//Prefix: p.space2prefix[tok.Name.Space],
140+
Type: ElementNode,
141+
Data: tok.Name.Local,
141142
NamespaceURI: tok.Name.Space,
142143
Attr: attributes,
143144
level: p.level,
144145
}
145-
// https://github.com/antchfx/xmlquery/issues/96
146-
if !(tok.Name.Space == defaultNameSpace) {
147-
node.Prefix = p.space2prefix[tok.Name.Space]
148-
}
146+
149147
if p.level == p.prev.level {
150148
AddSibling(p.prev, node)
151149
} else if p.level > p.prev.level {
@@ -156,6 +154,14 @@ func (p *parser) parse() (*Node, error) {
156154
}
157155
AddSibling(p.prev.Parent, node)
158156
}
157+
if node.NamespaceURI != "" {
158+
node.Prefix = p.space2prefix[node.NamespaceURI]
159+
if defaultNamespaceURL != "" && node.NamespaceURI == defaultNamespaceURL {
160+
node.Prefix = ""
161+
} else if n := node.Parent; n != nil && node.NamespaceURI == n.NamespaceURI {
162+
node.Prefix = n.Prefix
163+
}
164+
}
159165
// If we're in the streaming mode, we need to remember the node if it is the target node
160166
// so that when we finish processing the node's EndElement, we know how/what to return to
161167
// caller. Also we need to remove the target node from the tree upon next Read() call so

parse_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,56 @@ func TestLoadURLFailure(t *testing.T) {
8989
}
9090
}
9191

92+
func TestDefaultNamespace_1(t *testing.T) {
93+
s := `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
94+
<svg
95+
xmlns:svg="http://www.w3.org/2000/svg"
96+
xmlns="http://www.w3.org/2000/svg"
97+
>
98+
<text xml:space="preserve">
99+
<tspan>Multiline</tspan>
100+
<tspan>Multiline text</tspan>
101+
</text>
102+
</svg>`
103+
104+
doc, err := Parse(strings.NewReader(s))
105+
if err != nil {
106+
t.Fatal(err)
107+
}
108+
if n := FindOne(doc, "//svg"); n == nil {
109+
t.Fatal("should find a `svg` but got nil")
110+
}
111+
list := Find(doc, "//tspan")
112+
if found, expected := len(list), 2; found != expected {
113+
t.Fatalf("should found %d tspan but found %d", expected, found)
114+
}
115+
}
116+
117+
func TestDefaultNamespace_2(t *testing.T) {
118+
s := `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
119+
<svg
120+
xmlns="http://www.w3.org/2000/svg"
121+
xmlns:svg="http://www.w3.org/2000/svg"
122+
>
123+
<text xml:space="preserve">
124+
<tspan>Multiline</tspan>
125+
<tspan>Multiline text</tspan>
126+
</text>
127+
</svg>`
128+
129+
doc, err := Parse(strings.NewReader(s))
130+
if err != nil {
131+
t.Fatal(err)
132+
}
133+
if n := FindOne(doc, "//svg"); n == nil {
134+
t.Fatal("should find a `svg` but got nil")
135+
}
136+
list := Find(doc, "//tspan")
137+
if found, expected := len(list), 2; found != expected {
138+
t.Fatalf("should found %d tspan but found %d", expected, found)
139+
}
140+
}
141+
92142
func TestNamespaceURL(t *testing.T) {
93143
s := `
94144
<?xml version="1.0"?>

0 commit comments

Comments
 (0)