Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would an xpath position selection expression return multiple nodes?

Tags:

xml

xpath

While working with xpath (which hasn't been very long), I came across something odd.

Shortened version of the xml (The full xml is here and a snapshot is 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>

The expression

//route[1]

returned the first route node like I expected. However, when attempting to select the first message node, with

//message[1]

multiple message nodes were returned rather than just one.

At first I assumed that it was a platform problem, but testing on Android, Desktop Java and a couple of online xpath testers, I'm getting the same results.

What could be the problem?

like image 959
A--C Avatar asked Sep 02 '13 20:09

A--C


People also ask

What is XPath in Node JS?

XPath Operators. XPath. Operators. An XPath expression returns either a node-set, a string, a Boolean, or a number.

How to select nodes in an XML document using path expressions?

XPath uses path expressions to select nodes in an XML document. The node is selected by following a path or steps. The most useful path expressions are listed below: Expression. Description. nodename. Selects all nodes with the name " nodename ". /. Selects from the root node.

How to use XPath wildcards to select unknown XML nodes?

To solve this problem in IE, set the SelectionLanguage to XPath: XPath wildcards can be used to select unknown XML nodes. In the table below we have listed some path expressions and the result of the expressions: By using the | operator in an XPath expression you can select several paths.

How do I select multiple paths in an XPath expression?

By using the | operator in an XPath expression you can select several paths. In the table below we have listed some path expressions and the result of the expressions:


1 Answers

Both expressions represent the first route and message child of its parent, respectively.1 All of your routes are siblings sharing a single body parent, so the first of these is returned and only that. However each route contains its own set of message children, the first of which is being returned for every route node.

If you need to match the first message element in your entire XML document, use:

(//message)[1]

The parentheses tells the processor to find nodes matching //message, then the [1] predicate that comes after picks the first out of those nodes. Without them the [1] predicate will simply operate based on children of their parent node.


1Because I'm a CSS selector junkie: the selector counterparts for your XPath expressions are route:nth-of-type(1) and message:nth-of-type(1), respectively.

like image 72
BoltClock Avatar answered Sep 22 '22 23:09

BoltClock