基于xml到xsl对数据进行分组

时间:2016-09-21 10:28:33

标签: xml xslt xslt-1.0

我希望通过XSLT 1.0将数据分组到xml中,有人可以建议一种方法来实现。

<product>
  <group>
    <groupName>Maruthi</groupName>
    <groupOrderNumber>1</groupOrderNumber>
        <metaData>
          <metaDataName>sequenceOrderNumber</metaDataName>
          <metaDataValue>1</metaDataValue>             
       </metaData>
       <metaData>
          <metaDataName>HeaderName</metaDataName>
          <metaDataValue>Maruthi 800</metaDataValue>           
       </metaData>
  </group>
  <group>
    <groupName>Maruthi</groupName>
    <groupOrderNumber>1</groupOrderNumber>
        <metaData>
          <metaDataName>sequenceOrderNumber</metaDataName>
          <metaDataValue>2</metaDataValue>             
       </metaData>
       <metaData>
          <metaDataName>HeaderName</metaDataName>
          <metaDataValue>Maruthi Alto</metaDataValue>           
       </metaData>
  </group>
  <group>
    <groupName>Honda</groupName>
    <groupOrderNumber>2</groupOrderNumber>
        <metaData>
          <metaDataName>sequenceOrderNumber</metaDataName>
          <metaDataValue>1</metaDataValue>             
       </metaData>
       <metaData>
          <metaDataName>HeaderName</metaDataName>
          <metaDataValue>Honda City</metaDataValue>           
       </metaData>
  </group>
  <group>
    <groupName>Honda</groupName>
    <groupOrderNumber>2</groupOrderNumber>
        <metaData>
          <metaDataName>sequenceOrderNumber</metaDataName>
          <metaDataValue>2</metaDataValue>             
       </metaData>
       <metaData>
          <metaDataName>HeaderName</metaDataName>
          <metaDataValue>Honda Amaze</metaDataValue>           
       </metaData>
  </group>
</product>

我想显示如下内容,制造商订单基于组订单编号,模型订单基于sequenceOrderNumber。

Manufacturer: Maruthi
        Model: Maruthi800
        Model: Maruthi Alto
 Manufacturer: Honda
        Model: Honda City
        Model: Honda Amaze

请找到能够对数据进行分组的样式表,请建议我如何根据序列号订购。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:nms="http://www.example.org/consolidated"
 exclude-result-prefixes="nms"> 
<xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-    declaration="yes" />
<xsl:key name="groups" match="//nms:group" use="nms:groupName"/>
 <xsl:template match="/">
 <xsl:for-each select="//nms:group[count(. | key('groups',nms:groupName)[1]) = 1]">
 <xsl:sort select="nms:groupOrderNumber"/>     
 <table border="1">
 <tr> <xsl:value-of select="nms:groupName"/> </tr> 
 <xsl:for-each select="key('groups',nms:groupName)">                
      <xsl:for-each select="./nms:metaData">        
         <tr>
         <td><xsl:value-of select="nms:metaDataName"/> </td>
         <td><xsl:value-of select="nms:metaDataValue"/> </td>
         </tr>
     </xsl:for-each>
    </xsl:for-each> 
 </table>      
 </xsl:for-each> 
 </xsl:template>
</xsl:stylesheet> 

2 个答案:

答案 0 :(得分:0)

根据你没有指定XSLT版本的原始问题,我写了这个,这是 XSLT 2.0 中的解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="/*">
        <xsl:for-each-group select="//group" group-by="groupOrderNumber">
            Manufacturer: <xsl:value-of select="groupName"/><xsl:text>&#xd;</xsl:text>
            <xsl:for-each select="//group[groupOrderNumber=current-grouping-key()]">
                Model:<xsl:value-of select="metaData[metaDataName='HeaderName']/metaDataValue"/> <xsl:text>&#xd;</xsl:text>
            </xsl:for-each>
        </xsl:for-each-group>
        <xsl:text>&#xd;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

它使用xsl:for-each-group指令对groupOrderNumber分支中的group值进行分组。

然后,我使用内部current-grouping-key的{​​{1}}中的select来迭代与当前分组键匹配的组。

输出结果为:

xsl:for-each

您可能希望添加自己的格式,但由于我不知道任何特定的格式要求,因此上述XSLT至少应该为您提供所需内容的基础知识。

顺便说一句,我在输出中使用 Manufacturer: Maruthi Model:Maruthi 800 Model:Maruthi Alto Manufacturer: Honda Model:Honda City Model:Honda Amaze 作为回车符。

虽然这不适用于您使用的版本,但我会留下这个答案,以防任何在XSLT 2.0中寻找分组解决方案的人发现此问题。

答案 1 :(得分:0)

这仍然令人困惑,因为(a)你的样式表使用了前缀,但显示的输入没有命名空间,(b)你的样式表产生的输出与显示的输出不同。

我猜你想做点什么:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="groups" match="group" use="groupName"/>

<xsl:template match="/product">
    <xsl:for-each select="group[count(. | key('groups', groupName)[1]) = 1]">
        <xsl:sort select="groupOrderNumber"/>     
        <table border="1" width="250px">
            <tr>
                <th>Manufacturer</th>
                <td><xsl:value-of select="groupName"/></td>
            </tr> 
            <xsl:for-each select="key('groups', groupName)">  
                <xsl:sort select="metaData[metaDataName='sequenceOrderNumber']/metaDataValue"/>   
                <tr>
                    <th>Model</th>
                    <td><xsl:value-of select="metaData[metaDataName='HeaderName']/metaDataValue"/></td>
                </tr> 
            </xsl:for-each>
        </table>      
    </xsl:for-each> 
</xsl:template>

</xsl:stylesheet>