两个例子。这个样式表使用CLASIC全递归:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kNutChildByBisName" match="nutritionalValue/*"
use="../../@name"/>
<xsl:key name="kElemByPrecedingName" match="biscuit/*[not(self::name)]"
use="preceding-sibling::name[1]"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name" mode="group">
<bisquit>
<xsl:apply-templates select=".|key('kNutChildByBisName',.)|
key('kElemByPrecedingName',.)"/>
</bisquit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates mode="group"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="node()" mode="group"/>
</xsl:stylesheet>
而这个样式表使用细粒度遍历:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="kNutByBisName" match="nutritionalValue"
use="../@name"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="biscuit">
<xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="name[1]" name="group">
<bisquit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="key('kNutByBisName',.)/node()[1]"/>
</bisquit>
<xsl:apply-templates select="following-sibling::name[1]" mode="group"/>
</xsl:template>
<xsl:template match="name"/>
<xsl:template match="name" mode="group">
<xsl:call-template name="group"/>
</xsl:template>
</xsl:stylesheet>
有了这个输入:
<root>
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<name>Digestives</name>
<price>89.00</price>
</biscuit>
<biscuitInfo name="Hobnobs">
<nutritionalValue>
<fat>6 grams</fat>
<sugar>lots</sugar>
</nutritionalValue>
</biscuitInfo>
<biscuitInfo name="Digestives">
<nutritionalValue>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</nutritionalValue>
</biscuitInfo>
</root>
两个输出:
<root>
<bisquit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</bisquit>
<bisquit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</bisquit>
</root>
注意:您正在执行两项任务:分组和交叉引用。
编辑:在组中只有name
的情况下更好的细粒度遍历。
是否需要在xslt中创建一个变量来表示循环当前所关注的值?或者我可以直接在Xpath查询中使用它? – jdoig 2010-12-13 10:35:49
我认为这两个选项都可以有效。创建一个变量会给你更短的表达式,但我认为你可以在xpath查询中直接使用你的值。 – 2010-12-13 10:49:01
太好了,谢谢。我不认为你有什么好的链接显示这样的技术吗?只是为了救我挣扎。干杯。 – jdoig 2010-12-13 10:52:55