我很喜欢如何为下面编写递归循环。尝试逗号分开,但看起来循环只能起作用。有任何解决方案,想法会有所帮助吗?谢谢,我正在使用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>
</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>
</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
元素在内容上调用它。您的尝试根本不是很多,因为它不包含任何template
或call-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>