Using XQuery (in eXist-db 2.2), I am trying to process a set of XML elements and remove a single attribute from each element in the result set.
Example XML:
<results xmlns:abc="http://example.org">
<abc:element1 abc:selected="false" type="Class"/>
<abc:element2 abc:selected="false" type="Property"/>
</results>
The attribute to be removed is @abc:selected
. My question is, what is the difference between filtering an attribute set by fn:name vs. fn:node-name, when the attribute has an xs:QName?
If I use fn:node-name and compare to the xs:QName of the attribute, then @abc:selected
is not removed.
XQuery:
for $r in $results
let $name := node-name($r)
return
element {$name} {
$r/@*[node-name(.) != xs:QName('abc:selected')]
}
Result:
<results xmlns:abc="http://example.org">
<abc:element1 abc:selected="false" type="Class"/>
<abc:element2 abc:selected="false" type="Property"/>
</results>
However, if I use fn:name and compare to the string value of the attribute, then @abc:selected
is successfully removed.
XQuery:
for $r in $results
let $name := node-name($r)
return
element {$name} {
$r/@*[name(.) != 'abc:selected']
}
Result:
<results xmlns:abc="http://example.org">
<abc:element1 type="Class"/>
<abc:element2 type="Property"/>
</results>
What is the difference here? Why doesn't the first approach, with fn:node-name and xs:QName, work as I expect it to?
Looks like that isn't the proper way to create the expected xs:QName
instance. This expression xs:QName('abc:selected')
is throwing error "No namespace declared for prefix abc" for me (tested in BaseX).
You can use fn:QName()
which return xs:QName
instance instead, and that should properly remove abc:selected
attributes :
for $r in $results
let $name := node-name($r)
return
element {$name} {
$r/@*[node-name(.) ne QName('http://example.org', 'selected')]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.