0
votes

I have a xml like this,

<doc>
    <chap>
        <sec originator="ABC">
            <app originator="body">
                <sec originator="body">
                    <p>text</p>
                </sec>
            </app>
        </sec>
    </chap>
    <chap>
        <chap>
            <app originator="DEF">
                <sec originator="body">
                    <sec>
                        <p>text2</p>
                    </sec>
                </sec>
            </app>
        </chap>
    </chap>
    <sec originator="GHI">
        <sec originator="body">
            <p>text</p>
        </sec>
    </sec>
    <app originator="KLM">
        <sec>
            <sec>
                <p>text2</p>
            </sec>
        </sec>
    </app>
</doc>

I have written template for <p> node and from that I need to get the most distance ancestor <sec> or <app> node originator attribute value.

My xpath is

//p/(ancestor::app[@originator][last()] | ancestor::sec[@originator][last()])/@originator

This will select originator attribute values ABC, body, DEF, body, GHI, KLM.. But what I need is ABC, DEF, GHI, KLM.

How can I change my xpath to get most distance <sec> or <app> node originator attribute value

1

1 Answers

1
votes

In the context of a p element you can select ancestor::*[self::app[@originator] | self::sec[@originator]][last()]/@originator, see http://xsltransform.net/bFWR5EQ with

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">


    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="p">
        <p orig="{ancestor::*[self::app[@originator] | self::sec[@originator]][last()]/@originator}">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
</xsl:transform>

giving

<?xml version="1.0" encoding="UTF-8"?><doc>
    <chap>
        <sec originator="ABC">
            <app originator="body">
                <sec originator="body">
                    <p orig="ABC">text</p>
                </sec>
            </app>
        </sec>
    </chap>
    <chap>
        <chap>
            <app originator="DEF">
                <sec originator="body">
                    <sec>
                        <p orig="DEF">text2</p>
                    </sec>
                </sec>
            </app>
        </chap>
    </chap>
    <sec originator="GHI">
        <sec originator="body">
            <p orig="GHI">text</p>
        </sec>
    </sec>
    <app originator="KLM">
        <sec>
            <sec>
                <p orig="KLM">text2</p>
            </sec>
        </sec>
    </app>
</doc>