Reputation: 815
I have some XML text that looks like below, which I am transforming with XSL 3.0:
<deposition>
<seg>Lorem
<persName>P<supplied>etrus</supplied> Fabri
<roleName>textor</roleName>
<sic>apud</sic>
de Sancto Jacobo<persName> ipsum dolor sit amet,
consectetur adipiscing elit. Praesent vitae congue leo,
nec varius mauris. Vestibulum elementum arcu non
ultricies aliquam.</seg>
<seg>Ut pharetra bibendum ipsum, porttitor porttitor
velit pharetra quis. Aenean vel dolor purus. Praesent
aliquam viverra tellus in condimentum.</seg>
</deposition>
The transformation objective is below. This transformation adds a new <deposition-title>
from a transformed version of '', and <persName>
itself is transformed within <seg>
:
<deposition>
<deposition-title>P. Fabri de Sancto Jacobo<deposition-title>
<seg>Lorem P[etrus] Fabri textor de Sancto Jacobo
ipsum dolor sit amet,
consectetur adipiscing elit. Praesent vitae congue leo,
nec varius mauris. Vestibulum elementum arcu non
ultricies aliquam.</seg>
<seg>Ut pharetra bibendum ipsum, porttitor porttitor
velit pharetra quis. Aenean vel dolor purus. Praesent
aliquam viverra tellus in condimentum.</seg>
</deposition>
Obviously this 'treating' the <persName>
(and it's children element) twice.
I currently have templates transforming the elements inside <seg>
, for example:
<xsl:template match="supplied">
<xsl:text>[<xsl:text><xsl:apply-templates/><xsl:text>]<xsl:text>
</xsl:template>
<xsl:template match="sic"/>
But when it comes time to create the new <deposition-title>
element, I'm at a loss how to do it outside a very simple <xsl:value-of select="persName">
in a template copy:
<xsl:template match="deposition">
<xsl:copy>
<deposition-title><xsl:value-of select="persName"></deposition-title>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
Which just dumps out the text() nodes without processing them (as needed above):
<deposition-title>Petrus Fabri textor apud de Sancto Jacobo</deposition-title>
Ideally I'd like to call different versions of the templates to treat the elements differently.
Is there a way of somehow making a variety of templates for the same element for use and calling in different cases?
Added an example:
For the seg element, process this template which keeps roleName element:
<xsl:template match="roleName">
<xsl:text>[<xsl:text><xsl:apply-templates/><xsl:text>]<xsl:text>
</xsl:template>
But in creating the new deposition-title element, use this template which removes the roleName element:
<xsl:template match="roleName"/>
Upvotes: 0
Views: 38
Reputation: 70598
You could do this...
<deposition-title>
<xsl:value-of select="seg/persName/text()" separator=" " />
</deposition-title>
So, only get the direct child text nodes of seg/persName
. Although, you might want to tidy up the whitespace too...
<deposition-title>
<xsl:value-of select="seg/persName/text()[normalize-space()]/normalize-space()" />
</deposition-title>
Note, this assumes you only have one seg
with a persName
, otherwise you will get multiple names all put together as one.
If you do want to use different templates, rather than simply output text, you could make use of mode
<xsl:template match="deposition">
<xsl:copy>
<deposition-title>
<xsl:apply-templates select="seg/persName/node()" mode="title" />
</deposition-title>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="supplied" mode="title">
<xsl:text>.</xsl:text>
</xsl:template>
<xsl:template match="roleName" mode="title"/>
<xsl:template match="node()" mode="title">
<xsl:text> </xsl:text>
<xsl:value-of select="normalize-space()" />
</xsl:template>
You could use mode="#all"
for templates than can be used in any mode here.
<xsl:template match="sic" mode="#all" />
Upvotes: 1