Philippe Poulard wrote:
Joe Kesselman wrote:
Mat| wrote:
I am learning XPath, and I am trying to get child
nodes of a node whose names do *not* match a given
string,
/dummy/example/*[name()!="title"]
And while name() certainly does work, I also have to
agree with his warning that this will turn around and
bite you when you start working with namespaced
documents.
the best thing to do is :
/dummy/example/*[not(self::title )]
if you would use namespaces, it would become :
/foo:dummy/foo:example/*[not(self::foo:t itle)]
Definitely the most elegant solution.
Still, this got me thinking. While Philippe's solution
looks neat and works well, I have a feeling that the fact
you need to do something like that (that is, 'choose all
children but <title>s') is a fairly strong hint that you
should consider redesigning your XML structure (if you
have control over that, of course). For original poster's
sample that would be something like:
<dummy>
<example title="Example 1">
<body>this is an example</body>
<picture>a reference to a picture</picture>
</example>
</dummy>
or:
<dummy>
<example>
<title>Exampl e 1</title>
<body>
<content>this is an example</content>
<picture>a reference to a picture</picture>
</body>
</example>
</dummy>
What I probably mean to say (yeah, I'm not sure what I'm
sayin' myself), is that in case you need a predicate in
your XPath that somehow feels unnatural*, although the
nodes you need selected seem to belong to a well-defined,
logically natural group, it might be worth it to consider
changing the XML's structure to actually group those
nodes in a parent element.
* for some values of 'unnatural'
but if you use instead name() :
/foo:dummy/foo:example/*[name()!="foo:ti tle"]
...will give you the same result *only* if the XML
source do use the same prefix, which is somewhat
hazardous...
I wonder, by the way. Aren't
<foo:element xmlns:foo="foo"/>
and
<bar:element xmlns:bar="foo"/>
supposed to be two completely interchangeable
representations of the same document fragment? If they
are, isn't name() just a bit broken in that it makes
those two distinguishable ?
--
Pavel Lepin