2

So what I want to do is identify the 1st node in some subtree of a xml tree.

here's an example

<?xml version="1.0" encoding="utf-8"?>
<root>
  <road>
    <households>
      <household>
        <occupants>
          <person name="jim"/>
          <person name="jon"/>
          <person name="julie"/>
          <person name="janet"/>
        </occupants>
      </household>
      <household>
        <occupants>
          <person name="brenda"/>
          <person name="bert"/>
          <person name="billy"/>
        </occupants>
      </household>
    </households>
  </road>
  <road>
    <households>
      <household>
        <occupants>
        </occupants>
      </household>
      <household>
        <occupants>
          <person name="arthur"/>
          <person name="aimy"/>
        </occupants>
      </household>
      <household>
        <occupants>
          <person name="harry"/>
          <person name="henry"/>
        </occupants>
      </household>
    </households>
  </road>
</root>

now I want the 1st person mentioned per road.

so lets have a go...

/root/road/households/household/occupants/person[1]/@name

that returns the 1st person per occupants node.

lets try

(/root/road/households/household/occupants/person)[1]/@name

that returns the 1st person in the whole tree

what I sort of want to do is?

/root/road/(households/household/occupants/person)[1]/@name

i.e. take the 1st person in the set of people in a road

but thats not valid xpath 1.0

MrD at KookerellaLtd
  • 2,412
  • 1
  • 15
  • 17

1 Answers1

3

This seems to be what you’re after, using the descendant axis:

/root/road/descendant::person[1]/@name
matt
  • 78,533
  • 8
  • 163
  • 197
  • ok...it works!...I don't like it...I think because if I had some other persons in another hierachy it would give me the wrong answer, but I'll take it...thanks v much – MrD at KookerellaLtd Dec 23 '21 at 21:38
  • @MrDatKookerellaLtd you could add a predicate to `person` to restrict the match to only those from a particular hierarchy, using the `parent` or `ancestor` axes. For example something like `/root/road/descendant::person[ancestor::household][1]/@name` would only include those `person`s that are part of a `household`. It would depend on your actual data of course. – matt Dec 23 '21 at 22:03
  • yep....I always have half a mind on extensibility of the source XML, so I don't like pattern matches that break if someone extends the input schema...I wont worry about it though – MrD at KookerellaLtd Dec 24 '21 at 10:58