0

I have the following code:

    <Parent>
        <Map sourcename="ItemAName" destinationname="itemaname">
            <Assignment source="Test.OrderA.ItemA" destination="Test.OrderB.ItemA" sourcename="ItemAName" destinationname="ITEMANAME" description="descript3" mandatory="False"/>
            <Assignment source="Test.OrderB.ItemA" destination="Test.OrderC.ItemA" sourcename="ITEMANAME" destinationname="itemaname" description="descript3" mandatory="False"/>
        </Map>
        <Map sourcename="ItemAQuantity" destinationname="itemaquantity">
            <Assignment source="Test.OrderA.ItemA" destination="Test.OrderB.ItemA" sourcename="ItemAQuantity" destinationname="ITEMAQUANTITY" description="descript4" mandatory="False"/>
            <Assignment source="Test.OrderB.ItemA" destination="Test.OrderC.ItemA" sourcename="ITEMAQUANTITY" destinationname="itemaquantity" description="descript4" mandatory="False"/>
            <Assignment source="Test.OrderC.ItemA" destination="Test.OrderD.ItemA" sourcename="itemaquantity" destinationname="ItEmQuAnTiTy" description="descript4" mandatory="False"/>
        </Map>
    </Parent>

I want to display a table that contains 6 columns (number of assignments in the Map which contains more children * 2), in this case. Sometimes it will require more or less, according to the data in the xml file. If I add another map with four assignments, the table should have 8 columns.

I'm using this:

    <xsl:template match="Map">
        <xsl:if test="position() = 1">
            <tr class="bold">
                <xsl:for-each select="Assignment">
                    <td><xsl:value-of select="@source"/></td>
                    <td><xsl:value-of select="@destination"/></td>
                </xsl:for-each>
            </tr>
         </xsl:if>
         <tr>       
            <xsl:apply-templates select="Assignment"/>  
         </tr>
    </xsl:template> 

    <xsl:template match="Assignment">
        <td><xsl:value-of select="@sourcename" /></td>
        <td><xsl:value-of select="@destinationname" /></td>
    </xsl:template>

I know I should not use the if to test if its the first position. I need a way to count the number of assignments in the child who has more assignments.

Is there a way to do that?

Th3B0Y
  • 884
  • 1
  • 12
  • 30
  • Why don't you just generate a `` for each `` and a `` for each ``? HTML tables will already use the maximum number of columns that is used in any of the rows. – Erwin Bolwidt Feb 05 '14 at 15:04
  • @ErwinBolwidt , this is the actual code (I've updated here). I posted only the header part, which is the one I want to fix. But as it brings more questions, I have just updated it with the rest. – Th3B0Y Feb 05 '14 at 15:19
  • 1
    `xslt-1.0` and `xslt-2.0` are exclusive tags. Please say what version you are working with and remove one of them. – Mathias Müller Feb 05 '14 at 15:54
  • Will "empty" columns in a particular line always be at the end, in other words, is it possible for one row to have items A and B and another to have B and C (so you'd need three sets of columns A, B and C in total)? – Ian Roberts Feb 05 '14 at 16:02
  • seems like you need a to find the max of the count of Assignments within a Map http://stackoverflow.com/questions/1079715/xpath-function-max-doesnt-work and a counting loop http://stackoverflow.com/questions/9076323/xslt-looping-from-1-to-60 from 1 to that maximum to create column headers. Both are pretty hard in xslt 1.0 but doable in xslt 2.0. It's late here, if no one has an answer yet I'll check tomorrow – Erwin Bolwidt Feb 05 '14 at 16:06

2 Answers2

0

I suppose you need something like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xml:space="default" exclude-result-prefixes="" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" omit-xml-declaration="no" indent="yes" />
  <xsl:template match="Parent">
    <xsl:choose>
      <xsl:when test="count(./Map[@sourcename='ItemAName']/Assignment) &gt; count(./Map[@sourcename='ItemAQuantity']/Assignment)">
        Work on the map named ItemAName
    </xsl:when>
      <xsl:otherwise>
       Work on the map named ItemAQuantity
    </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • You are assuming there will be only two, although OP said: "*If I add another map with four assignments, the table should have 8 columns.*" – michael.hor257k Feb 06 '14 at 00:55
  • You're right. I misinterpreted that and thought that one of the maps would be changed to 4 items, but it's unknown which map will change. Thanks for the clarification. – Thomas Weller Feb 06 '14 at 07:03
0

I need a way to count the number of assignments in the child who has more assignments.

I suggest you put this at the top level of your stylesheet:

<xsl:variable name="columns">
    <xsl:for-each select="/Parent/Map">
    <xsl:sort select="count(Assignment)" data-type="number" order="descending"/>
    <xsl:if test="position()=1">
        <xsl:value-of select="2*count(Assignment)"/>
    </xsl:if>
    </xsl:for-each>
</xsl:variable>

Now you have the number of required columns in the $columns variable and can proceed to create them. If you prefer, you can tell the variable to copy the actual map with the most assignments, so that you can iterate over them when creating the columns.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51