Beast
Beast

Reputation: 629

Issue while using Preceding axis in XPath and XSLT

I am learning XSLT 2.0 and XPath. While creating the examples I came across to preceding axis available in XPath and created the below example.

Please find the below order.xml file used as input.

 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <Order id="12345">
    <Item>
        <ItemId>007</ItemId>
        <ItemName>iPhone 5</ItemName>
        <Price>500</Price>
        <Quantity>1</Quantity>
    </Item>
    <Item>
        <ItemId>456</ItemId>
        <ItemName>Ipad</ItemName>
        <Price>600</Price>
        <Quantity>2</Quantity>
    </Item>
    <Item>
        <ItemId>7864567</ItemId>
        <ItemName>Personal Development Book</ItemName>  
        <Price>10</Price>
        <Quantity>10</Quantity>
    </Item>
    <Item>
        <ItemId>123</ItemId>
        <ItemName>Java Book</ItemName>
        <Price>20</Price>
        <Quantity>12</Quantity>
    </Item>
</Order>

Please find the below XSLT testaxis.xsl file used for transformation of the above XML.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
     <xsl:value-of select="count(/Order/Item[ItemName='Ipad']/ItemName/preceding::*)" />
</xsl:template>

The output after transformation is 6

Here context node is below one if I am not wrong.

<ItemName>Ipad</ItemName>

If we count all the nodes which are before the context node then counts come to 5 . Now coming to the question, why it is showing the count of the nodes as 6 in the output?

Please do let me know if I misunderstood anything

Thanks in advance.

Upvotes: 1

Views: 659

Answers (2)

Michael Kay
Michael Kay

Reputation: 163575

The preceding elements are the ones marked below with a "*"

<*Item>
    <*ItemId>007</ItemId>
    <*ItemName>iPhone 5</ItemName>
    <*Price>500</Price>
    <*Quantity>1</Quantity>
</Item>
<Item>
    <*ItemId>456</ItemId>

You will see that there are six of them.

Upvotes: 1

JLRishe
JLRishe

Reputation: 101748

You are correct about which node is the context node, and that node does have 6 preceding elements:

  • The first <Item> element.
  • The four elements inside that.
  • The <ItemId> element immediately before the context node.

That makes six. You can verify this by doing the following:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text" />
 <xsl:template match="/">
   <xsl:for-each select="/Order/Item[ItemName='Ipad']/ItemName/preceding::*">
     <xsl:value-of select="concat(name(), '&#xA;')" />
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions