Question

I have a complex xml structure that looks like :

  <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>

Each <Item> has MANY more xml elements , but I won't specify them now.

I run with xsl on each Item like :

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

and I produce table with rows for each <Item> and many <td> in each row.

I need an example of how to group <ItemText> by <ItemTextsType> individually for each <Item> .

I will arrange the outcome in a table like :

 <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>

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

I have tried something like

<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>

but it only work on non repetitive nodes (if there were only one <Item>it would work fine). I can't change xml because it comes from customer .

Please help me , I need it ASAP .

Thank you !!!!

Was it helpful?

Solution

If you want a separate grouping for each Item then one way to achieve that would be to include some unique identifier for the containing Item as part of the key value, e.g.

<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))">

This would be much more straightforward if you could use XSLT 2.0 of course...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top