can't get the xpath working

  • Thread starter Michael Wohlwend
  • Start date
M

Michael Wohlwend

Hi,

this is my first xpath try and after reading many web-pages that xpath is
still not working :-(
(btw, it's my own project, not a homework)

I have something like that:

<root>
<one/>
<two>
<two-one/>
<two-two/>
</two>
<three>
<three-one>
<three-one-one/>
</three-one>
<three-two/>
</three>
</four>
</root>

I want all tags expect /root/two and root/three/three-one:

<root>
<one/>
<three>
<three-two/>
</three>
</four>
</root>


I have tried the following path, but it does not work:
getXPath("/root/*[name()!='two' and not(descendant::three-one/*)]

thanks for any enlightenment,
Michael
 
M

Martin Honnen

Michael said:
I have something like that:

<root>
<one/>
<two>
<two-one/>
<two-two/>
</two>
<three>
<three-one>
<three-one-one/>
</three-one>
<three-two/>
</three>
</four>
^^^^^^
not well-formed
I want all tags expect /root/two and root/three/three-one:

<root>
<one/>
<three>
<three-two/>
</three>
</four>
^^^^^^
not well-formed either
 
D

David Carlisle

Michael Wohlwend said:
Hi,

this is my first xpath try and after reading many web-pages that xpath is
still not working :-(
(btw, it's my own project, not a homework)

I have something like that:

<root>
<one/>
<two>
<two-one/>
<two-two/>
</two>
<three>
<three-one>
<three-one-one/>
</three-one>
<three-two/>
</three>
</four>
</root>

I want all tags expect /root/two and root/three/three-one:

Xpath doesn't deal with tags but with a node tree, this isn't just a
matter of naming, it explains your problem.

Xpath returns _unaltered_ nodes from a source tree and if you return the
element node with name "root" that will have all the same children and
grandchildren that it has in the source. So even if you only select the
single node, /root, you will get back the whole document, effectively.

the XPaths /root/two and root/three/three-one select the nodes that you
don't want to copy and you could use those in xslt or similar program to
specify the transformation that you want, but you can not select
the result below using XPath as that is not a subset of the nodes in the
original node set.
<root>
<one/>
<three>
<three-two/>
</three>
</four>
</root>


I have tried the following path, but it does not work:
getXPath("/root/*[name()!='two' and not(descendant::three-one/*)]

thanks for any enlightenment,
Michael


David
 
M

Michael Wohlwend

reclusive said:
Your XML is not valid. I would look here for how to write XML;

yes I have messed up a name for the example, the right closing tag is </one>
but the xpath is my problem

thanks
Michael
 
M

Michael Wohlwend

David said:
Xpath doesn't deal with tags but with a node tree, this isn't just a
matter of naming, it explains your problem.

Xpath returns _unaltered_ nodes from a source tree and if you return the
element node with name "root" that will have all the same children and
grandchildren that it has in the source. So even if you only select the
single node, /root, you will get back the whole document, effectively.

the XPaths /root/two and root/three/three-one select the nodes that you
don't want to copy and you could use those in xslt or similar program to
specify the transformation that you want, but you can not select
the result below using XPath as that is not a subset of the nodes in the
original node set.

but the following works for getting rid of node two:

"/root/*[name()!='two']

is gives:
<root>
<one/>
<three>
   <three-one> 
      <three-one-one/>
  </three-one>
   <three-two/>
</three>
</root>

just the node <three-one> should go away too. I thought this is easy, but it
seems, I cannot handle it with xpath

Michael

ps: I thought it's easier with number-nodes as an example, but no, normal
names would have been better :)
 
D

David Carlisle

but the following works for getting rid of node two:

"/root/*[name()!='two']

is gives:
<root>
<one/>

No. /root/*[name()!='two'] selects all the children of root except two
In particular it doesn't select the root element.
If you did select root then it would be returned unchanged (and would
have all its children).

David
 
C

C. M. Sperberg-McQueen

Michael Wohlwend said:
but the following works for getting rid of node two:

"/root/*[name()!='two']
is gives:
<root>
<one/>
<three>
  <three-one>
<three-one-one/>
  </three-one>
 <three-two/>
</three>
</root>

Ah, this is not what is denoted by "/root/*[name() != 'two']".

What's denoted by that XPath expression would be

<one/>
<three>
  <three-one>
<three-one-one/>
  </three-one>
 <three-two/>
</three>

I.e. two nodes, the set of children of /root whose generic
identifier is not 'two'.

Either a tool you are using is giving you a horribly wrong and
misleading result (it's returning a modified /root element
instead of the children of /root) or you may be
misinterpreting the correct result it's giving you.

Without knowing more about what tools you're using in what
context, it's hard to say more than that you should carefully
examine the evidence that led you to the belief quoted above.

I hope this helps.

-C. M. Sperberg-McQueen
World Wide Web Consortium
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,001
Messages
2,570,249
Members
46,846
Latest member
BettinaOsw

Latest Threads

Top