xsl分组两个不同的属性

时间:2014-12-03 21:06:48

标签: xml xslt

我有以下XML结构:

<table>
  <field1>User 1</field1>
  <field2>xyz</field2>
  <field3>xyz</field3>
</table>
<table>
  <field1>User 2</field1>
  <field2>abc</field2>
  <field3>xyz</field3>
</table>
<table>
  <field1>User 3</field1>
  <field2>def</field2>
  <field3>xyz</field3>
</table>
<table>
  <field1>User 2</field1>
  <field2>def</field2>
  <field3>xyz</field3>
</table>

XML有几百个表项。 属性可以在字段2或字段3中,也可以在两者中。

我需要一个输出,它将用户以及表格中字段2和3的属性分组。

<table border="1" cellspacing="0" cellpadding="0">
<tr>
    <td>Users</td>
    <td>abc</td>
    <td>def</td>
    <td>xyz</td>
</tr>
<tr>
    <td>User 1</td>
    <td> </td>
    <td> </td>
    <td>2</td>
</tr>
<tr>
    <td>User 2</td>
    <td>1</td>
    <td>1</td>
    <td>2</td>
</tr>
<tr>
    <td>User 3</td>
    <td> </td>
    <td>1</td>
    <td>1</td>
</tr>

在第二步中,我必须计算值,但这是另一个主题。

我只能使用XSLT 1.0,不幸的是我不知道如何对字段2和3中的值进行分组?

非常感谢您的支持!

1 个答案:

答案 0 :(得分:0)

假设您有一个格式正确的输入,例如:

<input>
    <object>
        <name>User 1</name>
        <color1>Red</color1>
        <color2>Red</color2>
    </object>
    <object>
        <name>User 2</name>
        <color1>Green</color1>
        <color2>Red</color2>
    </object>
    <object>
        <name>User 3</name>
        <color1>Blue</color1>
        <color2>Red</color2>
    </object>
    <object>
        <name>User 2</name>
        <color1>Blue</color1>
        <color2>Red</color2>
    </object>
</input>

应用以下样式表:

XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="object" match="object" use="name" />
<xsl:key name="color" match="color1 | color2" use="." />
<xsl:key name="color-by-object" match="color1 | color2" use="concat(../name, '|', .)" />

<xsl:variable name="columns">
    <xsl:for-each select="(input/object/color1 | input/object/color2)[count(. | key('color', .)[1]) = 1]">
        <color><xsl:value-of select="."/></color>
    </xsl:for-each>
</xsl:variable>
<xsl:variable name="col-set" select="exsl:node-set($columns)" />

<xsl:variable name="rows">
    <xsl:for-each select="input/object[count(. | key('object', name)[1]) = 1]">
        <xsl:copy-of select="name"/>
    </xsl:for-each>
</xsl:variable>
<xsl:variable name="row-set" select="exsl:node-set($rows)" />

<xsl:variable name="root" select="/" />

<xsl:template match="/input">
    <table border="1">
        <tr>
            <th/>
            <xsl:for-each select="$col-set/color">
                <th><xsl:value-of select="."/></th>
            </xsl:for-each>
        </tr>
        <xsl:for-each select="$row-set/name">
            <xsl:variable name="object" select="." />
            <tr>
                <th><xsl:value-of select="$object"/></th>
                <xsl:for-each select="$col-set/color">
                    <xsl:variable name="color" select="." />
                    <!-- switch to document in order to use key -->
                    <xsl:for-each select="$root">
                        <td><xsl:value-of select="count(key('color-by-object', concat($object, '|', $color)))"/></td>
                    </xsl:for-each>
                </xsl:for-each>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
   <tr>
      <th/>
      <th>Red</th>
      <th>Green</th>
      <th>Blue</th>
   </tr>
   <tr>
      <th>User 1</th>
      <td>2</td>
      <td>0</td>
      <td>0</td>
   </tr>
   <tr>
      <th>User 2</th>
      <td>2</td>
      <td>1</td>
      <td>1</td>
   </tr>
   <tr>
      <th>User 3</th>
      <td>1</td>
      <td>0</td>
      <td>1</td>
   </tr>
</table>

呈现为:

enter image description here