xsl grouping of repetitive nodes by xml element in xslt1

末鹿安然 提交于 2019-11-29 17:18:20

It's still difficult to tell what the desired solution is due to some discrepancies - for instance, your input XML has 4 <Item> elements, but your desired output only takes 3 of them into account. Additionally, several descriptions in your desired output do not match up with their expected location in the input XML document.

That said, if we focus on your stated desired solution:

"The point is that there is separate grouping for each <Item> into it's own <table> and inside that <table> there is groupping by <ItemTextsType>"

...then this ought to get you in the right direction.

When this XSLT:

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

  <xsl:key
    name="kItemTextByType"
    match="ItemText"
    use="concat(generate-id(ancestor::Item[1]), '+', ItemTextsType)" />

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/*">
    <table width="100%" border="1" style="display: block;">
      <tbody>
        <tr>
          <td id="SelectedRowLinkageContents">
            <xsl:apply-templates />
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="Item">
    <table width="100%" dir="ltr">
      <tbody>
        <tr style="background-color: #507CD1; text-align: center">
          <td colspan="3" style="font: bold; color: white">
            <xsl:value-of select="concat('Item', position())" />
          </td>
        </tr>
        <xsl:apply-templates 
          select="ItemTexts/ItemText[
            generate-id() = 
            generate-id(
              key(
                'kItemTextByType', 
                 concat(generate-id(current()), '+', ItemTextsType)
              )[1]
            )
          ]">
          <xsl:sort select="ItemTextsType" />
        </xsl:apply-templates>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="ItemText">
    <tr>
      <td style="height: 35px; font: bold; color: #507CD1;">
        <xsl:value-of select="ItemTextsType" />
      </td>
    </tr>
    <xsl:for-each
      select="key(
        'kItemTextByType', 
        concat(
          generate-id(ancestor::Item[1]),
          '+',
          ItemTextsType
        )
      )"
    >
      <xsl:sort select="ItemTextsTypeDesc" />
      <tr>
        <td>
          <xsl:value-of select="ItemTextsTypeDesc" />
        </td>
      </tr>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

...is applied to the provided input XML:

<?xml version="1.0" encoding="UTF-8"?>
<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>

...the wanted result is (I think) produced:

<table width="100%" border="1" style="display: block;">
  <tbody>
    <tr>
      <td id="SelectedRowLinkageContents">
        <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>
        <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>
        <table width="100%" dir="ltr">
          <tbody>
            <tr style="background-color: #507CD1; text-align: center">
              <td colspan="3" style="font: bold; color: white">Item3</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>
        <table width="100%" dir="ltr">
          <tbody>
            <tr style="background-color: #507CD1; text-align: center">
              <td colspan="3" style="font: bold; color: white">Item4</td>
            </tr>
            <tr>
              <td style="height: 35px; font: bold; color: #507CD1;">type2</td>
            </tr>
            <tr>
              <td>description21</td>
            </tr>
            <tr>
              <td>description22</td>
            </tr>
            <tr>
              <td style="height: 35px; font: bold; color: #507CD1;">
              type3</td>
            </tr>
            <tr>
              <td>description31</td>
            </tr>
            <tr>
              <td>description32</td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>

...which, when rendered in an HTML page, looks like this:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!