Reputation: 1060
I have an XML collection like this:
<test>
<test1></test1>
<test2></test2>
<test3>
<bla1></bla1>
<bla2></bla2>
</test3>
<test3></test3>
</test>
I want to get all the nodes except for the test3 nodes. I have tried /*[not(name()='test3')]
, but it does not work.
Also, is it possible with XPath to add a node to an XML collection? How can I do this?
Say I have XML like this:
<rootnode>
<node1></node1>
</rootnode>
and I want to add another node. How can I do this with XPath, or is this impossible?
I want to get all the nodes except for the test3 nodes (and its innernodes). so if there is a <bla>
in test2, I want to get it.
Finally, say that I want to filter the test3 nodes by index. So I want to remove all test3 nodes except for the first one (or the second or third, defined by the index I give).
How would one do this?
Upvotes: 1
Views: 490
Reputation: 243459
Now what I want to accomplish is the following, I want to get all the nodes except for the test3 nodes.
Use:
//node()[not(ancestor-or-self::test3)
and
not(self::processing-instruction('test3'))]
|
//*[not(ancestor-or-self::test3)]/@*[not(name()='test3')]
|
//*[not(ancestor-or-self::test3)]/namespace::*[not(name()='test3')]
Do note that in XPath every element is a node, but not every node is an element. The expression above selects every node in the document, whose name isn't test3
and that has no parent or ancestor named test3
.
There are the following types of nodes in the XPath data model:
document-node()
(also called "root node) -- selected by /
.
element()
node, selected by a name test in the child
axis, such as child::test3
just test3
or child::*
or just *
.
text()
node, selected by text()
.
comment()
node, selected by comment()
processing-instruction()
node, selected by processing-instruction()
or by processing-instruction('someName')
.
attribute()
node, selected by a name test on the attribute
axis, such as attribute::x
or @x
or @*
.
Namespace node, selected by a name test or a wild card on the namespace
axis, such as namespace::x
or namespace::*
.
Do note: The node- test node()
selects any of the above 7 types of nodes (which are allowed on the currently specified or default axis. Without axis specified, node()
selects any node of type 1 - 5 above.
Upvotes: 1
Reputation: 60190
1: You were only searching the root, but not the descendant nodes. Also, the name()
check should be avoided because it is unreliable when prefixes and namespaces are being used. Try this:
//*[not(ancestor-or-self::test3)]
2: XPath is querying XML only. However, there ar related technologies such as XSLT and XQuery which allow the transformation of XML. Or you can use a DOM in a programming language where you use XPath to identify the nodes and then operations on the DOM to modify them.
Upvotes: 2