Skip to content

Commit 0f42df8

Browse files
committed
fix #102
1 parent 40ea2e2 commit 0f42df8

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

parse.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,19 @@ func (p *parser) parse() (*Node, error) {
106106
}
107107
// https://www.w3.org/TR/xml-names/#scoping-defaulting
108108
var defaultNamespaceURL string
109+
// [#102], If found the duplicate NamespaceURL, we should saving into the loca
110+
// and use it instead of p.space2prefix.
111+
local_space2prefix := make(map[string]string)
109112
for _, att := range tok.Attr {
110113
if att.Name.Local == "xmlns" {
111114
p.space2prefix[att.Value] = "" // reset empty if exist the default namespace
115+
local_space2prefix[att.Value] = ""
112116
defaultNamespaceURL = att.Value
113117
} else if att.Name.Space == "xmlns" {
114118
if _, ok := p.space2prefix[att.Value]; !ok {
115119
p.space2prefix[att.Value] = att.Name.Local
120+
} else if defaultNamespaceURL != att.Value {
121+
local_space2prefix[att.Value] = att.Name.Local
116122
}
117123
}
118124
}
@@ -155,10 +161,16 @@ func (p *parser) parse() (*Node, error) {
155161
AddSibling(p.prev.Parent, node)
156162
}
157163
if node.NamespaceURI != "" {
158-
node.Prefix = p.space2prefix[node.NamespaceURI]
164+
var keepPrefix bool = true
165+
if prefix, ok := local_space2prefix[node.NamespaceURI]; ok {
166+
keepPrefix = true
167+
node.Prefix = prefix
168+
} else {
169+
node.Prefix = p.space2prefix[node.NamespaceURI]
170+
}
159171
if defaultNamespaceURL != "" && node.NamespaceURI == defaultNamespaceURL {
160172
node.Prefix = ""
161-
} else if n := node.Parent; n != nil && node.NamespaceURI == n.NamespaceURI {
173+
} else if n := node.Parent; n != nil && !keepPrefix && node.NamespaceURI == n.NamespaceURI {
162174
node.Prefix = n.Prefix
163175
}
164176
}

parse_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,28 @@ func TestDefaultNamespace_2(t *testing.T) {
139139
}
140140
}
141141

142+
func TestDuplicateNamespaceURL(t *testing.T) {
143+
s := `<?xml version='1.0' encoding='UTF-8'?>
144+
<S:Envelope
145+
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
146+
<S:Body test="1">
147+
<ns2:Fault
148+
xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"
149+
xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
150+
<faultcode>ns2:Client</faultcode>
151+
<faultstring>This is a client fault</faultstring>
152+
</ns2:Fault>
153+
</S:Body>
154+
</S:Envelope>`
155+
doc, err := Parse(strings.NewReader(s))
156+
if err != nil {
157+
t.Fatal(err)
158+
}
159+
n2 := FindOne(doc, `//S:Envelope/S:Body/ns2:Fault/faultcode`)
160+
if n2 == nil {
161+
t.Fatalf("should fount one but nil")
162+
}
163+
}
142164
func TestNamespaceURL(t *testing.T) {
143165
s := `
144166
<?xml version="1.0"?>

0 commit comments

Comments
 (0)