签入for-each循环xsl 1.0

时间:2013-02-05 11:45:40

标签: xml xslt xslt-1.0

我有一个包含多行数据的XML。

<abc>
 <def>some text1</def>
 <xyz>stack overflow</xyz>
</abc>
<abc>
 <def>some text2</def>
 <xyz>stack overflow 2)</xyz>
</abc>
<abc>
 <def>some text</def>
 <xyz>stack overflow 3)</xyz>
</abc>

现在我想在 XSL 1.0 中为此编写代码,它将开始检查每一行,即元素中的值/文本“2)”是否仅存在。 每当它在循环期间第一次遇到文本“2)”时,它应该打印“XSL_1.0 Programming”作为值并且应该退出循环。

3 个答案:

答案 0 :(得分:2)

你以错误的方式接近这一点 - XSLT不是一种程序性语言,并且没有办法退出循环&#34;。相反,您需要考虑如何以更具说明性的方式识别您感兴趣的节点。例如XPath表达式

abc[contains(., '2)')]

标识包含字符串的所有abc元素&#34; 2)&#34;在其后代文本节点中的任何位置,所以

(abc[contains(., '2)')])[1]

只提取第一个这样的元素,如果没有匹配的元素,则提取空节点集。如果您想处理abc元素,包括第一个包含&#34; 2)&#34;的元素,而不是任何后续元素,您可以使用类似

的内容
<xsl:for-each select="abc[not(preceding-sibling::abc[contains(., '2)')])]">

答案 1 :(得分:1)

正如Ian Roberts所解释的那样,没有在XSLT中打破循环的概念。您必须事先决定要处理哪些节点,并且听起来您只对包含第一个 abc 元素且包含'2)'的元素感兴趣。

在这里使用 xsl:apply-templates 实际上可能更好。

<xsl:apply-templates select="abc[not(preceding-sibling::abc[contains(xyz, '2)')])]" />

因此,这将选择所有没有前面的'2)'元素的元素。

接下来,您可以添加模板以匹配 abc 元素,具体取决于 xyz 元素的内容。例如,要输出“XSL_1.0 Programming”,如果它有'2)',请执行以下操作

<xsl:template match="abc[contains(xyz, '2)')]">
    <xsl:text>XSL_1.0 Programming</xsl:text>
</xsl:template>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/*">
        <xsl:apply-templates select="abc[not(preceding-sibling::abc[contains(xyz, '2)')])]" />
    </xsl:template>

    <xsl:template match="abc">
        <xsl:value-of select="concat(xyz, '&#10;')" />
    </xsl:template>

    <xsl:template match="abc[contains(xyz, '2)')]">
        <xsl:text>XSL_1.0 Programming&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

当应用于以下XML时(注意它有一个根元素)

<root>
<abc>
 <def>some text1</def>
 <xyz>stack overflow</xyz>
</abc>
<abc>
 <def>some text2</def>
 <xyz>stack overflow 2)</xyz>
</abc>
<abc>
 <def>some text3</def>
 <xyz>stack overflow</xyz>
</abc>
<abc>
 <def>some text</def>
 <xyz>stack overflow 3)</xyz>
</abc>
</root>

以下是输出

stack overflow
XSL_1.0 Programming

答案 2 :(得分:0)

这个怎么样:

<xsl:if test="abc[contains(xyz, '2)')]"> 
   <xsl:text>XSL_1.0 Programming</xsl:text> 
</xsl:if>