给出以下XML:
<results name="queryResults">
<int name="intfield1:[* TO 10]">11</int>
<int name="intfield2:[10 TO 20]">9</int>
<int name="intfield1:[10 TO 20]">12</int>
</results>
我想制作这个XML:
<results>
<field name="numberfield1">
<value name="[* TO 10]">11</value>
<value name="[10 TO 10]">12</value>
</field>
<field name="numberfield2">
<value name="[10 TO 20]">9</value>
</field>
</results>
我想不出怎么在XSL中这样做主要是因为我想要通过数字字段进行分组..所有我能想到的就是:
<xsl:if test="count(results/int) > 0">
<results>
<xsl:for-each select="results/int">
<field>
<xsl:attribute name="name">
<xsl:value-of select="substring-before(@name, ':')"/></xsl:attribute>
<value>
<xsl:attribute name="name">
<xsl:value-of select="substring-after(@name, ':') "/>
</xsl:attribute>
<xsl:value-of select="."/>
</value>
</field>
</xsl:for-each>
</results>
</xsl:if>
然而,这不会产生很好的分组列表,而是我得到了这个:
<results>
<field name="numberfield1">
<value name="[* TO 10]">11</value>
</field>
<field name="numberfield2">
<value name="[10 TO 20]">9</value>
</field>
<field name="numberfield1">
<value name="[10 TO 10]">12</value>
</field>
</results>
如果有人可以朝着正确的方向偷我......那会很棒吗?
由于
答案 0 :(得分:12)
要在XSLT 1.0中执行此操作,您必须使用名为"muenchian grouping"的技术。首先创建要分组的节点的密钥
<xsl:key name="intfield" match="int" use="substring-before(@name, ':')" />
接下来,您遍历所有节点,但只选择碰巧在相关组中的第一个节点
<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]">
接下来,您可以迭代使用密钥迭代组中的所有节点
<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/>
<xsl:for-each select="key('intfield', $intfieldname)">
将所有这些放在一起给出了
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="intfield" match="int" use="substring-before(@name, ':')"/>
<xsl:template match="/results">
<results>
<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]">
<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/>
<field>
<xsl:attribute name="name">
<xsl:value-of select="$intfieldname"/>
</xsl:attribute>
<xsl:for-each select="key('intfield', $intfieldname)">
<value>
<xsl:attribute name="name">
<xsl:value-of select="substring-after(@name, ':')"/>
</xsl:attribute>
<xsl:value-of select="."/>
</value>
</xsl:for-each>
</field>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
在您的示例中,“intfield”变为“numberfield”。在上面的示例中,我将名称保留为“intfield”。
答案 1 :(得分:3)
为了简化流程,W3C特别支持XSLT2.0中的分组。例如,见: http://www.xml.com/pub/a/2003/11/05/tr.html
但并非所有环境都支持XSLT2.0