XSL 更改 foreach 循环内的上下文节点
XSL changing context node inside foreach loop
我有以下 xml:
<project>
<workitem id="x1640" linecount="2">
<texts>
<text language="en" >English text in one line</text>
<text language="fr" >German text in <newline/>two lines</text>
<text language="de" >French text in <newline/>two lines</text>
</texts>
</workitem>
<workitem id="x1640" linecount="2">
</workitem>
</project>
我需要把它改成下面这样。
对于 text
中的每一行,我需要创建一个新的 textitem
元素,如下所示:
<root>
<textitem id="x1640-1">
<en>English text in one line</text>
<fr>German text in</fr>
<de>French text in</de>
</textitem>
<textitem id="x1640-2">
<en></en>
<fr>two lines</fr>
<de>two lines</de>
</textitem>
</root>
所以我的想法是在伪造的 for 循环中像这样迭代 linecount
,但这样我就失去了上下文节点。是否有机会将 foreach
中的上下文返回到 workitem
?还是我需要一种完全不同的方法?任何建议都会很好,谢谢!
<xsl:stylesheet version="2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="project/workitem" />
</root>
</xsl:template>
<xsl:template match="workitem">
<xsl:variable name="lines" select="1"/>
<!--
<xsl:for-each select="1 to ./@linecount">
-->
<textitem>
<xsl:attribute name="id"><xsl:value-of select="concat(@id,'-',$lines)" /></xsl:attribute>
<xsl:apply-templates select="texts/text" >
<xsl:with-param name="linecount" select="$lines" />
</xsl:apply-templates>
</textitem>
<!--
</xsl:for-each>
-->
</xsl:template>
<xsl:template match="text">
<xsl:param name="linecount"/>
<xsl:variable name="lang" select="@language" />
<xsl:element name="{$lang}">
<xsl:value-of select="./text()[count(preceding-sibling::newline)=($linecount - 1)]" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
如果您在 for-each
之前声明 <xsl:variable name="workitem" select="."/>
,您当然可以访问 for-each
内的变量 $workitem
。然后我建议使用或传递 for-each 的上下文项,即行号,并使用 text()[$line-nr]
到 select 适当的文本节点。
我有以下 xml:
<project>
<workitem id="x1640" linecount="2">
<texts>
<text language="en" >English text in one line</text>
<text language="fr" >German text in <newline/>two lines</text>
<text language="de" >French text in <newline/>two lines</text>
</texts>
</workitem>
<workitem id="x1640" linecount="2">
</workitem>
</project>
我需要把它改成下面这样。
对于 text
中的每一行,我需要创建一个新的 textitem
元素,如下所示:
<root>
<textitem id="x1640-1">
<en>English text in one line</text>
<fr>German text in</fr>
<de>French text in</de>
</textitem>
<textitem id="x1640-2">
<en></en>
<fr>two lines</fr>
<de>two lines</de>
</textitem>
</root>
所以我的想法是在伪造的 for 循环中像这样迭代 linecount
,但这样我就失去了上下文节点。是否有机会将 foreach
中的上下文返回到 workitem
?还是我需要一种完全不同的方法?任何建议都会很好,谢谢!
<xsl:stylesheet version="2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="project/workitem" />
</root>
</xsl:template>
<xsl:template match="workitem">
<xsl:variable name="lines" select="1"/>
<!--
<xsl:for-each select="1 to ./@linecount">
-->
<textitem>
<xsl:attribute name="id"><xsl:value-of select="concat(@id,'-',$lines)" /></xsl:attribute>
<xsl:apply-templates select="texts/text" >
<xsl:with-param name="linecount" select="$lines" />
</xsl:apply-templates>
</textitem>
<!--
</xsl:for-each>
-->
</xsl:template>
<xsl:template match="text">
<xsl:param name="linecount"/>
<xsl:variable name="lang" select="@language" />
<xsl:element name="{$lang}">
<xsl:value-of select="./text()[count(preceding-sibling::newline)=($linecount - 1)]" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="text()">
</xsl:template>
如果您在 for-each
之前声明 <xsl:variable name="workitem" select="."/>
,您当然可以访问 for-each
内的变量 $workitem
。然后我建议使用或传递 for-each 的上下文项,即行号,并使用 text()[$line-nr]
到 select 适当的文本节点。