XSLT:在不删除相邻元素的情况下对元素进行分组
XSLT: group elements without deleting neighboring elements
我想在 Word 文件中准备索引条目以进行 XSL-FO 转换。
索引条目总是以
开头
w:r/w:fldChar/@w:fldCharType="begin"
并以
w:r/w:fldChar/@w:fldCharType="end"
.
在两者之间,一个或多个元素可能包含该内容。
如何获取连续字符串形式的内容?
我已经尝试过 for-each-group 的不同变体。但问题是它总是删除不属于索引的其他 w:r。
我该怎么做?
来源-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>
XSLT 尝试之一
<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>
实际输出(简体)
<indexentry>
<w:r/>
<w:r/>
<w:r/>
</indexentry>
期望输出
<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>
对于外部 xsl:if
你想要一个 xsl:choose/xsl:when
而不是额外的 xsl:otherwise
将 current-group()
和 xsl:apply-templates
推送到你的默认模板(例如身份转换)。我不知道你是否需要内部xsl:if
和xsl:apply-templates
,我认为做<xsl:value-of select="current-group()[position() != last()]/w:r/w:instrText"/>
就足够了。
我想在 Word 文件中准备索引条目以进行 XSL-FO 转换。
索引条目总是以
开头w:r/w:fldChar/@w:fldCharType="begin"
并以
w:r/w:fldChar/@w:fldCharType="end"
.
在两者之间,一个或多个元素可能包含该内容。
如何获取连续字符串形式的内容?
我已经尝试过 for-each-group 的不同变体。但问题是它总是删除不属于索引的其他 w:r。
我该怎么做?
来源-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>
XSLT 尝试之一
<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>
实际输出(简体)
<indexentry>
<w:r/>
<w:r/>
<w:r/>
</indexentry>
期望输出
<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>
对于外部 xsl:if
你想要一个 xsl:choose/xsl:when
而不是额外的 xsl:otherwise
将 current-group()
和 xsl:apply-templates
推送到你的默认模板(例如身份转换)。我不知道你是否需要内部xsl:if
和xsl:apply-templates
,我认为做<xsl:value-of select="current-group()[position() != last()]/w:r/w:instrText"/>
就足够了。