Xml 执行一个“命令”;分组方式;XPath-XSL中的查询
给定以下XML:Xml 执行一个“命令”;分组方式;XPath-XSL中的查询,xml,xslt,xpath,xslt-1.0,Xml,Xslt,Xpath,Xslt 1.0,给定以下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> 11 9 12 我想生成以下XM
<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>
11
9
12
我想生成以下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>
11
12
9
我不知道如何在XSL中实现这一点,主要是因为我想按numbericfield进行分组。。我能想到的就是:
<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>
11
9
12
如果有人能把我带向正确的方向。。那太好了
感谢要在XSLT1.0中实现这一点,您必须使用一种称为的技术。首先创建要分组的节点的密钥
<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”
- 修正了打字错误
但是,并不是所有的环境都支持XSLT2.0。。干杯刚试过,效果不错。我必须查一下这个“麦恩教分组”的问题,因为现在它看起来像是巫毒的问题。。。有没有办法限制它创建的int字段。。因为还有另一个int的列表,它在哪里,它把这些带到intfield键中?希望这能使senseYep更准确,在xsl:key的“match”属性中,您可以输入任何完整的Xpath表达式,以更精确地了解您需要的节点。例如酷酷的班纳纳。。谢谢全部重新排序。。而且很有魅力。。我的用户将非常高兴..使用MS.NET,所以我只使用XSL 1.0。。不过你是对的。。这是一部天才的作品。。我将阅读该链接。谢谢