CanOfBees
CanOfBees

Reputation: 93

XSLT 2.0 - select following text() based on position

I'm stuck on trying to determine the correct predicate to access the text() following /document/meta/aff/sup/italic based on the value of /document/meta/contrib-group/contrib/ref/sup/italic.

Honestly I'm not even sure if I'm phrasing the question correctly. I know that there are text nodes in /document/meta/aff/, but I'm not sure how to get to them in the correct sequence. In the example XSLT below I've started to try using position() to determine the correct text, but I think I need additional predicates.

Thanks in advance for your time & trouble!

trailing-text-xml:

<?xml version="1.0" encoding="UTF-8"?>
<document>
<meta>
    <contrib-group>
        <contrib type="author">
            <name>
                <surname>Smith</surname>
                <given-name>Alan</given-name>
            </name>
            <ref type="aff">
                <sup>
                    <italic>a</italic>
                </sup>
            </ref>
        </contrib>
        <contrib type="author">
            <name>
                <surname>Jones</surname>
                <given-name>Beatrice</given-name>
            </name>
            <ref type="aff">
                <sup>
                    <italic>b</italic>
                </sup>
            </ref>
        </contrib>
        <contrib type="author">
            <name>
                <surname>Richardson</surname>
                <given-name>Clarence</given-name>
            </name>
            <ref type="aff">
                <sup>
                    <italic>c</italic>
                </sup>
            </ref>
        </contrib>
    </contrib-group>
    <aff>
        <sup>
            <italic>a</italic>
        </sup>An Institutional Name
        <sup>
            <italic>b</italic>
        </sup>An Institutional Name
        <sup>
            <italic>c</italic>
        </sup>An Institutional Name
    </aff>
</meta>
</document>

trailing-text-xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output method="text"/>
<xsl:template match="/">
    <xsl:apply-templates select="document/meta/contrib-group/contrib[@type='author']"/>
</xsl:template>

<xsl:template match="document/meta/contrib-group/contrib[@type='author']">
    <xsl:variable name="vPosition"
        select="position()"/>
    <xsl:text>Name: </xsl:text>
    <xsl:value-of select="concat(name/given-name, ' ', name/surname)"/>
    <xsl:text>&#x9;Affiliation: </xsl:text>
    <xsl:choose>
        <xsl:when test="ref/sup/italic = /document/meta/aff/sup/italic">
            <xsl:value-of select="concat(
                $vPosition,
                ' ',
                ref/sup/italic)"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Views: 115

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167561

I think you want to define a key and cross-reference:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output method="text"/>

<xsl:key name="aff" match="/document/meta/aff/sup[italic]" use="italic"/>

<xsl:template match="/">
    <xsl:apply-templates select="document/meta/contrib-group/contrib[@type='author']"/>
</xsl:template>

<xsl:template match="document/meta/contrib-group/contrib[@type='author']">
    <xsl:variable name="vPosition"
        select="position()"/>
    <xsl:text>Name: </xsl:text>
    <xsl:value-of select="concat(name/given-name, ' ', name/surname)"/>
    <xsl:text>&#x9;Affiliation: </xsl:text>
    <xsl:choose>
        <xsl:when test="key('aff', ref/sup/italic)">
            <xsl:value-of select="concat(
                $vPosition,
                ' ',
                key('aff', ref/sup/italic)/following-sibling::text()[1])"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

With your input I get the result

Name: Alan Smith        Affiliation: 1 An Institutional Name
       Name: Beatrice Jones    Affiliation: 2 An Institutional Name
       Name: Clarence Richardson       Affiliation: 3 An Institutional Name

Obviously the xsl:choose is a bit convoluted but you had that in there so I left it as posted and only changed the code to show how to cross-reference based on italic.

Upvotes: 2

Related Questions