我在一段时间后回到学习XSLT并发现自己在推送方法上苦苦挣扎。
来自以下(简化)文件:
<Index>
<Person id="Je1" age="30" nationality="Fra">Jean</Person>
<Person id="Ma1" age="30" nationality="Eng">Mary</Person>
<Person id="Je2" age="40" nationality="Fra">Jean</Person>
<Person id="Lu1" age="20" nationality="Ita">Luigi</Person>
<Person id="He1" age="50" nationality="Gre">Hector</Person>
<Person id="Pe1" age="45" nationality="Gre">Penelope</Person>
</Index>
我想: 1.使用属性&#34;国籍&#34;的不同值创建排序元素, 2.将项目传递给相应的元素 3.根据另一个原始属性对它们进行排序,例如&#34;年龄&#34;
<OrderedIndex>
<Country key="Eng">
<Person id="Ma1" age="30" nationality="E">Mary</Person>
</Country>
<Country key="Fra">
<Person id="Je1" age="30" nationality="F">Jean</Person>
<Person id="Je2" age="40" nationality="F">Jean</Person>
</Country>
<Country key="Gre">
<Person id="Pe1" age="45" nationality="Gre">Penelope</Person>
<Person id="He1" age="50" nationality="Gre">Hector</Person>
</Country>
<Country key="Ita">
<Person id="Lu1" age="20" nationality="Ita">Luigi</Person>
</Country>
</OrderedIndex>
我正在管理第一步:
<xsl:variable name="cou" select="distinct-values(//@nationality)"/>
<xsl:template match="*">
<xsl:text>
</xsl:text>
<List>
<xsl:for-each select="$cou">
<xsl:sort/>
<xsl:text>
</xsl:text>
<xsl:element name="country">
<xsl:attribute name="country">
<xsl:copy-of select="."/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
<xsl:text>
</xsl:text>
</List>
</xsl:template>
- 但在此之后我无法使用<apply-templates>
或<for-each>
。显然,在选择过程中我不明白。
感谢您的帮助!
答案 0 :(得分:1)
您的distinct-values
正在选择@n
属性,但我认为您的意思是选择@nationality
属性
<xsl:variable name="cou" select="distinct-values(//@nationality)"/>
但是,distinct-values
可能不是此处使用的最佳选择,因为它返回一系列原子值,因此您将不再处于原始XML文档的上下文中。 xsl:for-each-group
可能是更好的匹配
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/*">
<OrderedIndex>
<xsl:for-each-group select="Person" group-by="@nationality">
<xsl:sort select="@nationality"/>
<Country key="{current-grouping-key()}">
<xsl:apply-templates select="current-group()">
<xsl:sort select="@age" />
</xsl:apply-templates>
</Country>
</xsl:for-each-group>
</OrderedIndex>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意:
输出XML时确实没有必要尝试输出换行符(除非你有一些特殊要求)。只需使用indent
xsl:output
选项即可
身份模板用于复制Person
元素
请注意在key
元素上创建country
属性时使用Attribute Value Templates。
另请注意,如果您确实想使用distinct-values
,可以这样做......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:variable name="cou" select="distinct-values(//@nationality)"/>
<xsl:variable name="root" select="/"/>
<xsl:key name="people" match="Person" use="@nationality" />
<xsl:template match="/*">
<List>
<xsl:for-each select="$cou">
<xsl:sort select="." />
<country key="{.}">
<xsl:apply-templates select="apply-templates select="">
<xsl:sort select="@age" />
</xsl:apply-templates>
</country>
</xsl:for-each>
</List>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>