我的XML组织如下 -
<section name="Parent 1 Text here" ID="1" >
<section name="Child 1 Text here" ID="11">
</section>
<section name="Child 2 Text here" ID="12">
<section name="GrandChild Text here" ID="121" >
</section>
</section>
</section>
<section name="Parent 2 Text here" ID="2" >
<section name="Child 1 Text here" ID="22">
</section>
<section name="Child 2 Text here" ID="23">
<section name="GrandChild Text here" ID="232" >
</section>
</section>
</section>
我必须生成以下输出XML -
<section name="Parent 1 Text here" ID="1" >
<section name="Child 2 Text here" ID="12">
<section name="GrandChild Text here" ID="121" >
</section>
</section>
</section>
<section name="Parent 2 Text here" ID="2" >
<section name="Child 2 Text here" ID="23">
</section>
</section>
我必须在上面使用XSLT 1.0转换。我打算将逗号分隔的字符串作为参数传递,其值为“1,12,121,2,23”
我的问题 - 如何在XSLT 1.0中循环逗号分隔参数? 是否有更简单的方法来实现上述目标。请记住我必须在XSLT 1.0中执行此操作 感谢您的帮助。
答案 0 :(得分:2)
递归不一定是解决方案。基本上你的逗号分隔字符串可以用作过滤器:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="filter">1,12,121,2,23</xsl:param>
<xsl:template match="section">
<xsl:if test="contains(concat(',', $filter, ','), concat(',', @ID, ','))">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- copy the rest -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
这是Jan Willem B的方法的替代方案。我并不认为它好或坏。我提出这个有两个原因:
您可能希望看到递归方法的样子
对于某些输入数据,它的行为有所不同(尽管它对您的示例数据的行为相同)。具体来说,如果您的过滤器包含两个节点,这两个节点都是同一节点的后代,则此样式表将输出两个嵌套数据结构,每个结构都有一个叶节点,而Jan Willem B的答案输出一个具有两个叶节点的嵌套结构。不知道你想要哪一个。
对于我的样式表,您将传递一个过滤器,仅列出您想要的叶节点。它会找到祖先。我假设您的根节点名为&lt; doc&gt;
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:param name="descendant-ids" select="'121,23'"/>
<xsl:template match="/">
<doc>
<xsl:call-template name="recurse-ids">
<xsl:with-param name="ids" select="concat($descendant-ids,',')"/>
</xsl:call-template>
</doc>
</xsl:template>
<xsl:template name="recurse-ids">
<xsl:param name="ids"/>
<xsl:variable name="id" select="substring-before($ids,',')"/>
<xsl:variable name="remaining-ids" select="substring-after($ids,',')"/>
<xsl:apply-templates select="/doc/section">
<xsl:with-param name="id" select="$id"/>
</xsl:apply-templates>
<xsl:if test="$remaining-ids">
<xsl:call-template name="recurse-ids">
<xsl:with-param name="ids" select="$remaining-ids"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="section">
<xsl:param name="id"/>
<xsl:if test="starts-with($id,@ID)">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="id" select="$id"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>