Why does the xpath position select expression return multiple nodes?

While working with xpath (which was not very long), I came across something strange.

Shortened version of xml (full xml here and snapshot available on pastebin ):

<?xml version="1.0" encoding="utf-8" ?> <body copyright="All data copyright San Francisco Muni 2013."> <route tag="all"> <message id="10268" creator="jflynn" startBoundary="1378121400000" startBoundaryStr="Mon, Sep 02 04:30:00 PDT 2013" endBoundary="1378191540000" endBoundaryStr="Mon, Sep 02 23:59:00 PDT 2013" sendToBuses="false"> <text>Sunday schedules today.</text> </message> </route> <route tag="44"> <message id="10221" creator="mlee" startBoundary="1377525600000" startBoundaryStr="Mon, Aug 26 07:00:00 PDT 2013" endBoundary="1382857140000" endBoundaryStr="Sat, Oct 26 23:59:00 PDT 2013" sendToBuses="false"> <routeConfiguredForMessage tag="44"> <stop tag="6420" title="Silver Ave &amp; Revere Ave" /> </routeConfiguredForMessage> <text>Stop moved&#10;across Revere&#10;During&#10;Construction</text> </message> <message id="10222" creator="mlee" startBoundary="1377525600000" startBoundaryStr="Mon, Aug 26 07:00:00 PDT 2013" endBoundary="1382857140000" endBoundaryStr="Sat, Oct 26 23:59:00 PDT 2013" sendToBuses="false"> <routeConfiguredForMessage tag="44"> <stop tag="6420" title="Silver Ave &amp; Revere Ave" /> </routeConfiguredForMessage> <text>Stop moved&#10;across Revere&#10;During&#10;Construction</text> </message> </route> </body> 

Expression

 //route[1] 

returned the first route node as I expected. However, when trying to select the first message node with

 //message[1] 

several message nodes were returned, not just one.

At first I suggested that this is a platform problem, but testing on Android, Desktop Java and a couple of online xpath testers I get the same results.

What could be the problem?

+6
source share
1 answer

Both expressions represent the first child of route and message its parent, respectively. 1 All of your route are siblings sharing the same parent body , so the first one they return and only that. However, each route contains its own set of message children, the first of which is returned for each route node.

If you need to map the first message element in the whole XML document, use:

 (//message)[1] 

The brackets tell the processor to find the nodes corresponding to //message , and then the predicate [1] , which appears after selecting the first of these nodes. Without them, the predicate [1] will simply work based on the children of its parent nodes.


1 Since I am a CSS junkie selector: for selector copies for XPath expressions, route:nth-of-type(1) and message:nth-of-type(1) respectively.

+8
source

Source: https://habr.com/ru/post/953006/


All Articles