-1

I have this XML structure:

<?version="1.0" encoding="ISO-8859-1" ?>
  <feed xmlns="http://www.w3.org/2005/Atom" >
    <companyinfo>
      <addresses>
        <address type="mailing" >
          <city>NEW YORK</city>
        </address>
        <address type="business" >
          <city>NEW YORK</city>
        </address>
        <node1>node1</node1>
        <node2>node2</node2>
        <node3>nod3</node3>
      </addresses>
    </companyinfo>
  </feed>

I want to select all children of <companyinfo> but exclude addresses from the result. Meaning my selection becomes all the <nodeX>.

After reading around and looking at related threads this and this, I came up with the following:

//companyinfo[not(addresses)] # does not work

//companyinfo/*[not(addresses)] # does not work

Am I misunderstanding how not(expr) works?

Am I actually trying to select companyinfo IF addresses node is not present?

rock3t
  • 2,193
  • 2
  • 19
  • 24

1 Answers1

0

Your xml is invalid, but if you fix it (and the typo), this expression, though convoluted,

//*[local-name()="companyinfo"]//*[local-name()="addresses"]//*[not(ancestor-or-self::*[local-name()="address"])]

should output

node1
node2
node3
Jack Fleeting
  • 24,385
  • 6
  • 23
  • 45
  • It does work! It works as well like this: //*[local-name()="addresses"]//*[not(ancestor-or-self::*[local-name()="address"])]. Are you able to explain why it needs to be done like that? – rock3t Oct 04 '20 at 05:20
  • @rock3t You don't really need with `companyinfo` just like you don't need to deal with `feed`; the critical node is `addresses` and its children. The reason you have to go through this `local-name()` process is the concept of namespaces. It's a long and sometimes painful subject and you need to learn about it. Start, for example, with: https://stackoverflow.com/a/6397369/9448090. – Jack Fleeting Oct 04 '20 at 10:44