user3872094
user3872094

Reputation: 3351

Confused in selecting ancestor name

I'm trying to print ancestor node name using XSLT.

Below is my XSLT.

<xsl:apply-templates select="(//title)[1]"/>

<xsl:template match="title">
<xsl:value-of select="name(ancestor::node())"/>
</xsl:template>

And my XML is as below.

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
    <!--ancestor-->
    <cd>
        <!--parent-->
        <title name="titleName" property="propertyName">Empire Burlesque</title>
        <!--self-->
        <artist>Bob Dylan</artist>
        <!--following-sibling-->
        <country>USA</country>
        <!--following-sibling-->
        <company>Columbia</company>
        <!--following-sibling-->
        <price>10.90</price>
        <!--following-sibling-->
        <year>1985</year>
        <!--following-sibling-->
    </cd>
</catalog>

Here when I use the below statement.

<xsl:value-of select="name(../..)"/>

else when I use

<xsl:value-of select="name(ancestor::node())"/>

or

<xsl:value-of select="name(ancestor::*)"/>

it is giving me the below Exception

XSLT 2.0 Debugging Error: Error: file:///C:/Users/u0138039/Desktop/Training%20Docs/XSLT%20Training/Sample.xsl:209: Wrong occurrence to match required sequence type -   Details: -     XPTY0004: The parameter value ('3' item(s)) at position '1' of the 'name' function has the wrong occurrence to match the sequence type node() ('zero or one')

but to get the parent name, when I use

<xsl:value-of select="name(parent::*)"/>

please let me know why this working for parent but not for ancestor.

This is very confusing. How can I get the ancestor name using something like <xsl:value-of select="name(ancestor::node())".

Thanks

Upvotes: 1

Views: 1330

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116957

The ancestor axis contains all ancestors of the context node: its parent, its grandparent, its great-grandparent, etc. all the way up to the root node.

When you ask for a name of an ancestor, you must select one of the nodes on the ancestor axis. For example:

<xsl:value-of select="name(ancestor::*[last()])"/>

will return "catalog" in your example (note that ancestor is a reverse axis).

OTOH, this:

<xsl:value-of select="ancestor::*/name()"/>

will (in XSLT 2.0) return "catalog cd" - i.e. a space-separated list of all the node's ancestor names.

Upvotes: 2

Related Questions