要做的第一件事就是将源XML转换为适当的形式。
XML文档包含只有一个根标签(让我们称之为主) 和该标签可以包含多个源代码(例如,对象)。
每个标签(如你在串写标签)可以包含属性有值 (在你的情况名和为了),但它们之间必须是“=”标志。
在对象标签的情况下,你记得把在“/”关闭标签, 但你在每个关串标签忘了。
所以正确的输入XML(需要更正后)为:
<main>
<object>
<string name="order">1</string>
<string name="item">1</string>
</object>
<object>
<string name="order">1</string>
<string name="item">2</string>
</object>
<object>
<string name="order">2</string>
<string name="item">1</string>
</object>
</main>
现在让我们倒在主业。 在描述中我把行号 - 引用到最终的解决方案。
我们从xsl:输出indent =“是”(第2行)开始,否则所有内容 将在单行(难以阅读)中。
该XML代码包含单个tempate匹配主要标记(第4行)。
它所做的第一件事是拷贝(开启和关闭主标签 - 第5行)。
然后,第6行包含分组循环(,针对每个组)。细分电子邮件广告是对象元素中的对象(参见选择子句)和分组关键是串子标签的含量(相对于当前对象)与属性名称等于“命令”(见组 - 由子句)。
所以第一组包含对象标签号1和2(它们都具有 字符串名称=“顺序”标签用的“1”的内容和所述第二组包含 对象标签号3。
然后(对于每组源对象标签)
我们创建输出对象元件(第7行),该元件必须具有一个ATT ribute命名为order与当前分组键(第8行)的值为 。
当前元素(输出对象)是包含在 当前组从每个元素数据,所以我们必须写的for-each语句,通过 所有源循环对象标签 - 的含量(请参阅选择子句,第9行)。
在此循环中,对于每个输入对象,我们创建了一个字符串元素(第10行)。
这个元素有一个名为“名”的属性(见名条款)和 其值应为“项目”(见选择条款) - 行11
的最后一件事要做的就是创建输出标签的内容 - 与 属性的名项目值 价值孩子串标签的(相对于当前对象) - 行12
XSL中的所有其他行都是结束标记。
下面有一个完整的XSL解决方案。
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="main">
<xsl:copy>
<xsl:for-each-group select="object" group-by="string[@name='order']">
<xsl:element name="object">
<xsl:attribute name="order" select="current-grouping-key()"/>
<xsl:for-each select="current-group()">
<xsl:element name="string">
<xsl:attribute name="name" select="'item'"/>
<xsl:value-of select="string[@name='item']"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>
这是*分组*问题。做一个搜索 - 这可能是最经常被问到的XSLT问题。请注意,对于XSLT 1.0或2.0,答案是不同的。 –