xsl按xml元素分组,用于xslt1中的重复节点到html表输出

时间:2012-11-14 10:46:15

标签: xml xslt xml-parsing xslt-1.0 xsl-grouping

我有一个复杂的xml结构,如下所示:

  <Items>
      <Item>
          <ItemTexts>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
              <ItemTextsLine>1</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
              <ItemTextsLine>2</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
              <ItemTextsLine>3</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
              <ItemTextsLine>4</ItemTextsLine>
            </ItemText>
          </ItemTexts>
         </Item>
    <Item>
          <ItemTexts>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
              <ItemTextsLine>1</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
              <ItemTextsLine>2</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
              <ItemTextsLine>3</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
              <ItemTextsLine>4</ItemTextsLine>
            </ItemText>
          </ItemTexts>
         </Item>
<Item>
          <ItemTexts>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
              <ItemTextsLine>1</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type1</ItemTextsType>
              <ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
              <ItemTextsLine>2</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
              <ItemTextsLine>3</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
              <ItemTextsLine>4</ItemTextsLine>
            </ItemText>
          </ItemTexts>
         </Item>
    <Item>
          <ItemTexts>
            <ItemText>
              <ItemTextsType>type3</ItemTextsType>
              <ItemTextsTypeDesc>description31</ItemTextsTypeDesc>
              <ItemTextsLine>1</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type3</ItemTextsType>
              <ItemTextsTypeDesc>description32</ItemTextsTypeDesc>
              <ItemTextsLine>2</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
              <ItemTextsLine>3</ItemTextsLine>
            </ItemText>
            <ItemText>
              <ItemTextsType>type2</ItemTextsType>
              <ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
              <ItemTextsLine>4</ItemTextsLine>
            </ItemText>
          </ItemTexts>
         </Item>
    </Items>

每个<Item>都有更多的xml元素,但我现在不会指定它们。

我在每个项目上使用xsl运行,如:

<xsl:for-each select="Items/Item">

我为每个<Item>制作了包含行的表格,并在每行中生成了许多<td>

我需要一个示例,说明如何针对每个<ItemText><ItemTextsType>分别<Item>

我会将结果安排在如下表格中:

 <table>
    <%--tr for each Item in Items--%>
    <tr>
        <td>
            some value from xml element according <b> Item1 </b>
        </td>
        <td>
            some more value from xml element according <b> Item1 </b>
        </td>
        <%--
        .
        .
        .
--%>
        <td>
            <table width="100%" dir="ltr">
                <tbody>
                    <tr style="background-color: #507CD1; text-align: center">
                        <td colspan="3" style="font: bold; color: white">
                            Item1
                        </td>
                    </tr>
                    <tr>
                        <td style="height: 35px; font: bold; color: #507CD1;">
                            type1
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description11
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description12
                        </td>
                    </tr>
                    <tr>
                        <td style="height: 35px; font: bold; color: #507CD1;">
                            type2
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description21
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description22
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
        <td>
            even more value from xml element according <b> Item1 </b>
        </td>
        <%--
        .
        .
        .
        --%>
    </tr>
   <tr>
        <td>
            some value from xml element according <b> Item2 </b>
        </td>
        <td>
            some more value from  xml element according <b> Item2 </b>
        </td>
        <%--
        .
        .
        .
--%>
        <td>
            <table width="100%" dir="ltr">
                <tbody>
                    <tr style="background-color: #507CD1; text-align: center">
                        <td colspan="3" style="font: bold; color: white">
                            Item2
                        </td>
                    </tr>
                    <tr>
                        <td style="height: 35px; font: bold; color: #507CD1;">
                            type1
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description11
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description12
                        </td>
                    </tr>
                    <tr>
                        <td style="height: 35px; font: bold; color: #507CD1;">
                            type2
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description21
                        </td>
                    </tr>
                    <tr>
                        <td>
                            description22
                        </td>
                    </tr>
                </tbody>
            </table>
        </td>
        <td>
            even more value from according <b> Item2 </b>
        </td>
        <%--
        .
        .
        .
        --%>
    </tr>
   <%-- and so on--%>
</table>

关键是每个<Item>都有单独的分组到自己的<tr><td><table>内,<table>内部有<ItemTextsType>

我尝试了类似

的内容
<xsl:key name="item-texts-type" match="ItemText" use="ItemTextsType" />


<xsl:for-each select="ItemTexts/ItemText[count(. | key('item-texts-type', ItemTextsType)[1]) = 1]">

                        <xsl:sort select="ItemTextsType" />
                        <tr>
                          <td style ="height:35px;font: bold; color:#507CD1;">
                            <xsl:value-of select="ItemTextsType" />
                          </td>
                        </tr>

                        <xsl:for-each select="key('item-texts-type', ItemTextsType)">
                          <tr>
                            <td>
                               <xsl:value-of select="ItemTextsTypeDesc" />
                            </td>
                          </tr>
                        </xsl:for-each>


                      </xsl:for-each>

但它只适用于重复节点(如果只有一个<Item>它可以正常工作)。 我无法更改xml,因为它来自客户。

请帮助我,我需要尽快。

谢谢!!!!

1 个答案:

答案 0 :(得分:1)

如果你想为每个Item单独分组,那么实现这一目的的一种方法是包含一些包含Item的唯一标识符作为键值的一部分,例如

<xsl:key name="item-texts-type" match="ItemText"
         use="concat(generate-id(ancestor::Item), '|', ItemTextsType)" />

<!-- assuming the context node is the current Item -->
<xsl:variable name="currentItemId" select="generate-id()" />

<xsl:for-each select="ItemTexts/ItemText[count(. | key('item-texts-type',
        concat($currentItemId, '|', ItemTextsType))[1]) = 1]">
  <!-- .... -->
  <xsl:for-each select="key('item-texts-type',
        concat($currentItemId, '|', ItemTextsType))">

如果你当然可以使用XSLT 2.0,这会更直接......