Subject: Re: [xsl] Generate separate elements, not just attribute values From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Thu, 23 Mar 2017 19:59:25 -0000 |
> On 23 Mar 2017, at 18:23, Charles O'Connor coconnor@xxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > 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> You could be a lot less verbose: > <xsl:template match="//contrib[not(xref/@ref-type='aff')]"> > <xsl:copy> > <xsl:apply-templates select="@* | node()"/> > <xref ref-type="aff" id="{../aff/@id}"/> > </xsl:copy> > </xsl:template> > > > 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? Yes, you do: <xsl:for-each select="../aff"> <xref ref-type="aff" id="{@id}"/> </xsl:for-each> > 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? > Because in XSLT 1.0, xsl:value-of (and many other operations), if given a set of nodes as input, ignores all but the first node in the set. Michael Kay
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Generate separate elements, n, Charles O'Connor coc | Thread | Re: [xsl] Generate separate element, Martin Honnen martin |
[xsl] Generate separate elements, n, Charles O'Connor coc | Date | Re: [xsl] Generate separate element, Martin Honnen martin |
Month |