[xsl] Generate separate elements, not just attribute values

Subject: [xsl] Generate separate elements, not just attribute values
From: "Charles O'Connor coconnor@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Mar 2017 18:23:28 -0000
Hi all,

Extreme novice here, so I appreciate your help.

Using XSLT 2.0 (explained later) and Saxon9 HE.

I have JATS 1.1 (archiving) input:

. . .

<contrib-group>
	<contrib contrib-type="author">
		<name>
			<surname>Franzke</surname>
			<given-names>Christian L. E.</given-names>
		</name>
	</contrib>
	<aff id="aff2">Meteorological Institute and Center for Earth System Research
and Sustainability (CEN), <institution>University of Hamburg</institution>,
<country>Germany</country></aff>
	<aff id="aff3">Department of Cheddar, <institution>University of Curds and
Whey</institution>, <country>Land of Cheese</country></aff>
</contrib-group>

. . .

To make it easier for our engineers to recognize relationships between
<contrib>s and <aff>s in cases where they are related through nesting in a
<contrib-group>, not <xref>s, I wrote a small .xsl:

<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:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="//contrib[not(xref/@ref-type='aff')]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:element name="xref">
                <xsl:attribute name="ref-type">aff</xsl:attribute>
                <xsl:attribute name="rid">
                    <xsl:value-of select="parent::contrib-group/aff/@id"/>
                </xsl:attribute>
            </xsl:element>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Which gives as output

. . .

<contrib-group>
	<contrib contrib-type="author">
		<name>
			<surname>Franzke</surname>
			<given-names>Christian L. E.</given-names>
		</name>
		<xref ref-type="aff" rid="aff2 aff3"/>
	</contrib>
	<aff id="aff2">Meteorological Institute and Center for Earth System Research
and Sustainability (CEN), <institution>University of Hamburg</institution>,
<country>Germany</country></aff>
	<aff id="aff3">Department of Cheddar, <institution>University of Curds and
Whey</institution>, <country>Land of Cheese</country></aff>
</contrib-group>

. . .

But in cases of more than one <aff> in a <contrib-group>, instead of

	<xref ref-type="aff" rid="aff2 aff3"/>

it turns out the engineers really want

	<xref ref-type="aff" rid="aff2"/><xref ref-type="aff" rid="aff3"/>

Do I need to use a "for-each" to do this? I was beginning to think I was
halfway clever when I figured out I didn't need a "for-each" to get the
initial .xsl to work, but maybe not so clever after all.

Incidental question: I have the version as 2.0 because, well, that was the
version on the identity template I copied from wherever. I didn't see any
reason for it to be 2.0, however, and 1.0 would be easier because you can run
1.0 in .NET without additional software. But, when I changed the version to
1.0, it ran fine but only gave the first @rid value, i.e.,

<xref ref-type="aff" rid="aff2"/>

Why?

Thanks,
Charles



Charles O'Connor l Business Analyst
Aries Systems Corporation l www.ariessys.com
200 Sutton Street l North Andover, MA l 01845 l USA
Direct: 802-585-5655 Main: 978-975-7570 l Help Desk: 978-291-1966 | Fax:
978-975-3811

Current Thread