我有以下场景,我从未做过嵌套转换,我不知道如何开始。我有以下样本。如果该值具有两位数,则它成为所有后代的祖先。
输入:
<Items Title="Title" Icon="Icon" Description="Description">
<Item Value="01" Name="Agriculture"/>
<Item Value="011" Name="Horticulture and Fruit Growing"/>
<Item Value="0111" Name="Plant Nurseries"/>
<Item Value="011101" Name="Bulb Propagating"/>
<Item Value="0112" Name="Cut Flower and Flower Seed Growing"/>
<Item Value="011201" Name="Display Foliage Growing"/>
... ......值继续
欲望输出:
<Items Title="Title" Icon="Icon" Description="Description">
<Item Name="Agriculture">
<Item Value="011" Name="Horticulture and Fruit Growing">
<Item Value="0111" Name="Plant Nurseries">
<Item Value="011101" Name="Bulb Propagating" />
</Item>
<Item Value="0112" Name="Cut Flower and Flower Seed Growing">
<Item Value="011201" Name="Display Foliage Growing" />
</Item>
</Item>
</Item>
...
我使用了以下xslt:
<xsl:template match="Items">
<Items Title="{@Title}" Icon="{@Icon}" Description="{@Description}">
<xsl:for-each select="Item">
<xsl:if test="string-length(@Value) = 2">
<Item Name="{@Name}">
<xsl:for-each select="ancestor::Items/Item">
<xsl:if test="string-length(@Value) = 3">
<Item Value="{@Value}" Name="{@Name}">
</Item>
</xsl:if>
</xsl:for-each>
</Item>
</xsl:if>
</xsl:for-each>
</Items>
</xsl:template>
但这不适用于4级和6级。
现在的结果是:
<Items Title="Title" Icon="Icon" Description="Description">
<Item Name="Agriculture">
<Item Value="011" Name="Horticulture and Fruit Growing"/>
...
答案 0 :(得分:1)
你可以使用xsl:for-each-group group-starting-with
解决这个问题,因为你想要处理几个级别,最好写一个递归函数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element(Item)*">
<xsl:param name="items" as="element(Item)*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$items" group-starting-with="Item[string-length(@Value) eq $level]">
<xsl:choose>
<xsl:when test="self::Item[string-length(@Value) eq $level]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:sequence select="mf:group(current-group() except ., min((current-group() except .)/string-length(@Value)))"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="mf:group(current-group(), min(current-group()/@Value))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Items">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:sequence select="mf:group(Item, 2)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>