一旦条件成立,我需要立即退出每个循环。并希望在循环中断的地方返回当前索引。下面是我的示例xml和xslt
<xsl:stylesheet xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="Data">
<xsl:element name="Data">
<xsl:call-template name="TempData" />
</xsl:element>
</xsl:template>
<xsl:template name="TempData">
<xsl:element name="TempData">
<xsl:for-each select="/Data/Subject/SubTest">
<xsl:choose>
<xsl:when test="@System='OK' and @SubFlag!='1'">
<xsl:attribute name="CurrentSubFlag">
<xsl:value-of select="position()" />
</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<xsl:copy-of select="TempData/*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<Data>
<Subject>
<SubTest SubFlag="1" System="OK"> </SubTest>
<SubTest SubFlag="csdcd" System="OK"> </SubTest>
<SubTest SubFlag="zxczx" System="OK"> </SubTest>
</Subject>
<TempData CurrentSubFlag="abc"/>
</Data>
输出xml应该是
<Data>
<Subject>
<SubTest SubFlag="1" System="OK"> </SubTest>
<SubTest SubFlag="csdcd" System="OK"> </SubTest>
<SubTest SubFlag="zxczx" System="OK"> </SubTest>
</Subject>
<TempData CurrentSubFlag="2"/>
</Data>
如果输入为
<Data>
<Subject>
<SubTest SubFlag="1" System="OK"> </SubTest>
<SubTest SubFlag="1" System="OK"> </SubTest>
<SubTest SubFlag="1" System="OK"> </SubTest>
</Subject>
<TempData CurrentSubFlag="abc"/>
</Data>
然后输出将是相同的CurrentSubFlag =“ abc”
答案 0 :(得分:3)
xsl:for-each
不是循环,无需循环或递归即可实现所需的结果。
给出:
XML
<Data>
<Subject>
<SubTest SubFlag="1" System="OK"> </SubTest>
<SubTest SubFlag="csdcd" System="OK"> </SubTest>
<SubTest SubFlag="zxczx" System="OK"> </SubTest>
</Subject>
<TempData CurrentSubFlag="abc"/>
</Data>
以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TempData">
<xsl:variable name="index" select="count(/Data/Subject/SubTest[not(@SubFlag=1 and @System='OK')][1]/preceding-sibling::SubTest) + 1" />
<TempData CurrentSubFlag="{$index}"/>
</xsl:template>
</xsl:stylesheet>
将返回:
结果
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Subject>
<SubTest SubFlag="1" System="OK"/>
<SubTest SubFlag="csdcd" System="OK"/>
<SubTest SubFlag="zxczx" System="OK"/>
</Subject>
<TempData CurrentSubFlag="2"/>
</Data>
要适应您所添加的条件,请尝试:
<xsl:template match="TempData">
<xsl:variable name="fail" select="/Data/Subject/SubTest[not(@SubFlag=1 and @System='OK')]" />
<xsl:choose>
<xsl:when test="$fail">
<TempData CurrentSubFlag="{count($fail[1]/preceding-sibling::SubTest) + 1}"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 1 :(得分:0)
您要问的内容等同于while循环。这可以通过具有变量的递归模板来完成(请参见How to do a "while"-like loop in XSLT?或http://www.humbug.in/2010/a-sample-loop-in-xsl-alternative-for-while-for-loops-2/)。
使用伪代码:
function findFirst(elements)
foreach element in elements
if test(element)
return element
与:
function findFirst(elements, offset)
element = elements[offset]
if test(element)
return element
else
return findFirst(elements, offset + 1)
后者可以通过递归模板来完成(请参见链接)
(注意:代码假定该元素存在)