I want to prepare the index entries in a Word file for an XSL-FO transformation.
The index entry always starts with
w:r/w:fldChar/@w:fldCharType="begin"
and ends with
w:r/w:fldChar/@w:fldCharType="end"
.
In between, one or more elements may contain the content.
How do I get the content as a contiguous string?
I have tried it with different variants of for-each-group. But the problem is that it always removes the other w:r that are not part of the index.
How can I do this?
Source-XML
<w:p>
<w:r>
<w:t>Stahl und Beton</w:t>
</w:r>
<w:r>
<w:t>lässt</w:t>
</w:r>
<w:r>
<w:t> sich aus dem alten Namen des Materials ableiten.</w:t>
</w:r>
<w:r>
<w:fldChar w:fldCharType="begin"/>
<w:r>
<w:instrText> XE "</w:instrText>
</w:r>
<w:r>
<w:instrText>Moniereisen</w:instrText>
</w:r>
<w:r>
<w:instrText>" </w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType="end"/>
</w:r>
</w:p>
One of the XSLT attempts
<xsl:template match="w:p[w:r[w:fldChar[@w:fldCharType = 'begin']]]">
<xsl:for-each-group select="*" group-starting-with="w:r[w:fldChar[@w:fldCharType = 'begin']]">
<xsl:if test="self::w:r[w:fldChar/@w:fldCharType = 'begin']">
<indexentry>
<xsl:for-each-group select="current-group()[position() gt 1]"
group-ending-with="w:r[w:fldChar[@w:fldCharType = 'end']]">
<xsl:if test="position() eq 1">
<xsl:apply-templates
select="current-group()[not(self::w:r[w:fldChar[@w:fldCharType = 'end']])]"/>
</xsl:if>
</xsl:for-each-group>
</indexentry>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
Actual output (simplified)
<indexentry>
<w:r/>
<w:r/>
<w:r/>
</indexentry>
Desired output
<w:p>
<w:r>
<w:t>Stahl und Beton</w:t>
</w:r>
<w:r>
<w:t>lässt</w:t>
</w:r>
<w:r>
<w:t> sich aus dem alten Namen des Materials ableiten.</w:t>
</w:r>
<indexentry> XE "Moniereisen" </indexentry>
</w:p>
CodePudding user response:
For the outer xsl:if
you want an xsl:choose/xsl:when
instead where the additional xsl:otherwise
pushes the current-group()
with xsl:apply-templates
to your default templates (e.g. the identity transformation). I don't know whether you need the inner xsl:if
and the xsl:apply-templates
, I would think that doing <xsl:value-of select="current-group()[position() != last()]/w:r/w:instrText"/>
suffices.