如何为逗号分隔节点编写递归循环



我很喜欢如何为下面编写递归循环。尝试逗号分开,但看起来循环只能起作用。有任何解决方案,想法会有所帮助吗?谢谢,我正在使用XML版本1。以下只是一个示例。

我的XML来源:

<Groceries>
    <fruit>Apple,Banana,Peach,Lemon</fruit>
</Groceries>

我正在寻找XSLT以获取下面的输出。
因此,我所需的XML输出应该看起来像:

<Foods>
      <Food raw="Lemon" cat="Fruit" val="Lemon"/>
      <Food raw="Apple" cat="Fruit" val="Apple"/>
      <Food raw="Peach" cat="Fruit" val="Peach"/>
      <Food raw="Banana" cat="Fruit" val="Banana"/>
</Foods>

我创建XSLT解决方案的尝试是:

<xsl:element name="Fruit">
  <xsl:attribute name="raw">
    <xsl:value-of select="substring-before(fruit,',')"/>
  </xsl:attribute>
  <xsl:attribute name="cat">Fruit</xsl:attribute>
  <xsl:attribute name="val">
    <xsl:value-of select="substring-before(fruit,',')"/>
  </xsl:attribute>
</xsl:element>
<xsl:text>&#xa;</xsl:text>
<xsl:element name="Fruit">
  <xsl:attribute name="raw">
    <xsl:value-of select="substring-after(fruit,',')"/>
  </xsl:attribute>
  <xsl:attribute name="cat">Fruit</xsl:attribute>
  <xsl:attribute name="val">
    <xsl:value-of select="substring- after(fruit,',')"/>
  </xsl:attribute>
</xsl:element>
<xsl:text>&#xa;</xsl:text>

谢谢

带有递归模板的XSLT-1.0可实现所需的结果:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/Groceries">
      <Foods>
        <xsl:call-template name="fruit">           <!-- call the recursive template -->
          <xsl:with-param name="txt" select="concat(fruit/text(),',')" />  <!-- add a leading ',' to make the recursive template behave properly -->
        </xsl:call-template>
      </Foods>
    </xsl:template>
    <xsl:template name="fruit">
      <xsl:param name="txt" />
      <xsl:if test="$txt != ''">
        <xsl:variable name="x" select="normalize-space(substring-before($txt,','))"/>
        <Food raw="{$x}" cat="Fruit" val="{$x}" />  <!-- add 'Food' element with attributes -->
        <xsl:call-template name="fruit">            <!-- call the recursive template with the rest of the comma-separated-string -->
          <xsl:with-param name="txt" select="normalize-space(substring-after($txt,','))" />
        </xsl:call-template>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

它的输出是根据所需的:

<?xml version="1.0"?>
<Foods>
    <Food raw="Apple" cat="Fruit" val="Apple"/>
    <Food raw="Banana" cat="Fruit" val="Banana"/>
    <Food raw="Peach" cat="Fruit" val="Peach"/>
    <Food raw="Lemon" cat="Fruit" val="Lemon"/>
</Foods>

您通过给 template元素一个名称来构建递归模板,如果满足某些条件,请将其调用,并使用call-template元素在内容上调用它。您的尝试根本不是很多,因为它不包含任何templatecall-template元素,也不是有效的XSLT样式表。

此代码将递归产生所述的输出,包括所描述的输出元素的看似随机顺序。

<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <output media-type="application/xml"/>
    <template name="parse.CSV.string">
        <param name="CSV.string.element"/>
        <param name="CSV.string" select="string($CSV.string.element/child::text())"/>
        <param name="required.item.string" select="string($CSV.string.element/child::text())"/>
        <variable name="item.string">
            <choose>
                <when test="contains($CSV.string, ',')">
                    <value-of select="substring-before($CSV.string, ',')"/>
                </when>
                <otherwise>
                    <value-of select="$CSV.string"/>
                </otherwise>
            </choose>
        </variable>
        <choose>
            <when test="$item.string = $required.item.string">
                <element name="Food">
                    <attribute name="raw">
                        <value-of select="$item.string"/>
                    </attribute>
                    <attribute name="cat">Fruit</attribute>
                    <attribute name="val">
                        <value-of select="$item.string"/>
                    </attribute>
                </element>
            </when>
            <when test="contains($CSV.string, ',')">
                <call-template name="parse.CSV.string">
                    <with-param name="CSV.string.element" select="$CSV.string.element"/>
                    <with-param name="CSV.string" select="substring-after($CSV.string, ',')"/>
                    <with-param name="required.item.string" select="$required.item.string"/>
                </call-template>
            </when>
        </choose>
    </template>
    <template match="/child::Groceries">
        <element name="Foods">
            <call-template name="parse.CSV.string">
                <with-param name="CSV.string.element" select="child::fruit"/>
                <with-param name="required.item.string" select="'Lemon'"/>
            </call-template>
            <call-template name="parse.CSV.string">
                <with-param name="CSV.string.element" select="child::fruit"/>
                <with-param name="required.item.string" select="'Apple'"/>
            </call-template>
            <call-template name="parse.CSV.string">
                <with-param name="CSV.string.element" select="child::fruit"/>
                <with-param name="required.item.string" select="'Peach'"/>
            </call-template>
            <call-template name="parse.CSV.string">
                <with-param name="CSV.string.element" select="child::fruit"/>
                <with-param name="required.item.string" select="'Banana'"/>
            </call-template>
        </element>
    </template>
</transform>

相关内容

  • 没有找到相关文章

最新更新