0

I'm trying to transform some XML and I'm not really sure if it's possible.

  1. Is this even possible to achieve?
  2. How might I update the translate to accomplish it?

I want to group these instances by the academic year and output the rest of the instance content in a table with columns/rows for each instance. The year would become the heading, and the remaining content would appear in the table. If there was also some instances of 2014, that would be a new heading and new table.

<courses>
  <course>
  <uuid>123</uuid>
            <coursetitle>Being better at XSLT</coursetitle>
            <coursetypes>
              <coursetype>Postgraduate</coursetype>
            </coursetypes>
   <instances> 
        <instance> 
              <uuid>1054EDE3F28D9873</uuid> 
              <instancecode>MPW1F</instancecode> 
              <year>2013</year> 
          </instance> 

          <instance> 
              <uuid>D9FC4501-F504-B560-FB8DFC3EF41C0E1F</uuid> 
              <instancecode>MPO1F</instancecode> 
              <year>2013</year> 
           </instance> 

          <instance> 
              <uuid>D9FC5017-0789-16A0-C8BBD0F0BE016E6F</uuid> 
              <instancecode>MPW2F</instancecode> 
              <year>2013</year> 
          </instance> 

          <instance> 
              <uuid>D9FC4963-A684-565A-5AA282A7CEC7B4CC</uuid> 
              <instancecode>MPO2F</instancecode> 
              <year>2013</year> 
          </instance> 
    </instances> 
  </course>
    <course>
  <uuid>1234</uuid>
            <coursetitle>Being better at XML</coursetitle>
            <coursetypes>
              <coursetype>Postgraduate</coursetype>
            </coursetypes>
   <instances> 
        <instance> 
              <uuid>1054EDE3F28D9873</uuid> 
              <instancecode>MPW1F</instancecode> 
              <year>2014</year> 
          </instance> 

          <instance> 
              <uuid>D9FC4501-F504-B560-FB8DFC3EF41C0E1F</uuid> 
              <instancecode>MPO1F</instancecode> 
              <year>2014</year> 
           </instance> 

          <instance> 
              <uuid>D9FC5017-0789-16A0-C8BBD0F0BE016E6F</uuid> 
              <instancecode>MPW2F</instancecode> 
              <year>2013</year> 
          </instance> 

          <instance> 
              <uuid>D9FC4963-A684-565A-5AA282A7CEC7B4CC</uuid> 
              <instancecode>MPO2F</instancecode> 
              <year>2013</year> 
          </instance> 
    </instances> 
  </course>
</courses>

I've had a look at XSLT 1.0 - Create a Unique, Ordered List but it only seems to work on grouping items relative the root.

This is the transform we're trying to run* and it seems to work on the first occurance of the year 2013 however the next course instances are ignored (assuming because it has already found an instance of that year).

**note that I removed some of the content that this is printing from the code above for the sake of being a little cleaner*

<!-- Instances -->
    <xsl:template match="instances">
        <xsl:for-each select="./instance[applicationmethod != 'NO_APP' and applicationmethod != '' and generate-id()= generate-id(key('acyear',year)[1])]">
            <xsl:sort select="year" />
            <xsl:value-of select="./year"/>,
        </xsl:for-each>
        <xsl:apply-templates select="./instance">
            <xsl:sort select="year"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="instance">
        <xsl:if test="./applicationmethod != 'NO_APP' and ./applicationmethod != ''">
        &lt;li&gt;
            <xsl:text>&lt;strong&gt;UUID:&lt;/strong&gt;</xsl:text><xsl:value-of select="./uuid"/>
            <xsl:text>, &lt;strong&gt;Instance Code:&lt;/strong&gt;</xsl:text><xsl:value-of select="./instancecode"/>
            <xsl:text>, &lt;strong&gt;Year:&lt;/strong&gt;</xsl:text><xsl:value-of select="./academicyear"/>
            <xsl:text>, &lt;strong&gt;Course Year:&lt;/strong&gt;</xsl:text><xsl:value-of select="./courseyear"/>
            <xsl:text>, &lt;strong&gt;Start Date:&lt;/strong&gt;</xsl:text><xsl:value-of select="./startdate"/>
            <xsl:text>, &lt;strong&gt;End Date:&lt;/strong&gt;</xsl:text><xsl:value-of select="./enddate"/>
            <xsl:text>, &lt;strong&gt;Display From:&lt;/strong&gt;</xsl:text><xsl:value-of select="./displayfrom"/>
            <xsl:text>, &lt;strong&gt;Display To:&lt;/strong&gt;</xsl:text><xsl:value-of select="./displayto"/>
            <xsl:text>, &lt;strong&gt;Mode of Study:&lt;/strong&gt;</xsl:text><xsl:value-of select="./modeofstudy"/>
            <xsl:text>, &lt;strong&gt;Application Method:&lt;/strong&gt;</xsl:text><xsl:value-of select="./applicationmethod"/>
            <xsl:text>, &lt;strong&gt;Apply Link:&lt;/strong&gt;</xsl:text><xsl:value-of select="./applylink"/>
            <xsl:text>, &lt;strong&gt;Cost:&lt;/strong&gt;</xsl:text><xsl:value-of select="./cost"/>
            <xsl:text>, &lt;strong&gt;Day and Time:&lt;/strong&gt;</xsl:text><xsl:value-of select="./dayandtime"/>
        &lt;/li&gt;
        </xsl:if>
    </xsl:template>

Output

Each course will be a different page, but the content would look like

Being better at XSLT
Postgraduate

2013

  • MPW1F
  • MPO1F
  • MPW2F
  • MPO2F

Being better at XML
Postgraduate

2014

  • MPW1F
  • MPO1F

2013

  • MPW2F
  • MPO2F
4

1 回答 1

1

Sounds like you have to group the instance belonging to one course by year. This could be done with a key like the following one:

<xsl:key name="kCourseInstaneByYears" match="instance" use="concat(ancestor::course/uuid, '|' , year)"/>

This assume that the course/uuid is unique for courses.

With this key you can try something like this (surly not complete but should show the idea).

?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="kCourseInstaneByYears" match="instance" use="concat(ancestor::course/uuid, '|' , year)"/>

    <xsl:template match="/*">
        <html>
            <body>
                <xsl:apply-templates select="//course" />
            </body>
        </html>
    </xsl:template>

    <xsl:template match="course">
        <xsl:variable name ="courseID" select="uuid" />
        <h1>
            <xsl:value-of select="coursetitle"  />
        </h1>
        <xsl:for-each select="descendant::instance[generate-id() = 
                                    generate-id(key('kCourseInstaneByYears', concat($courseID, '|' , year))[1])]"  >
            <xsl:sort select="year"/>

            <xsl:variable name="year" select="year" />
            <h2>
                <xsl:value-of select="$year"/>
            </h2>
            <table>
                <xsl:apply-templates select="key('kCourseInstaneByYears', concat($courseID, '|' , $year))" />


            </table>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="instance" >
        <tr>
            <td>
                <xsl:value-of select="uuid"/>
            </td>
            <td>
                <xsl:value-of select="instancecode"/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

Which will generate the following output:

<html>
  <body>
    <h1>Being better at XSLT</h1>
    <h2>2013</h2>
    <table>
      <tr>
        <td>1054EDE3F28D9873</td>
        <td>MPW1F</td>
      </tr>
      <tr>
        <td>D9FC4501-F504-B560-FB8DFC3EF41C0E1F</td>
        <td>MPO1F</td>
      </tr>
      <tr>
        <td>D9FC5017-0789-16A0-C8BBD0F0BE016E6F</td>
        <td>MPW2F</td>
      </tr>
      <tr>
        <td>D9FC4963-A684-565A-5AA282A7CEC7B4CC</td>
        <td>MPO2F</td>
      </tr>
    </table>
    <h1>Being better at XML</h1>
    <h2>2013</h2>
    <table>
      <tr>
        <td>D9FC5017-0789-16A0-C8BBD0F0BE016E6F</td>
        <td>MPW2F</td>
      </tr>
      <tr>
        <td>D9FC4963-A684-565A-5AA282A7CEC7B4CC</td>
        <td>MPO2F</td>
      </tr>
    </table>
    <h2>2014</h2>
    <table>
      <tr>
        <td>1054EDE3F28D9873</td>
        <td>MPW1F</td>
      </tr>
      <tr>
        <td>D9FC4501-F504-B560-FB8DFC3EF41C0E1F</td>
        <td>MPO1F</td>
      </tr>
    </table>
  </body>
</html>
于 2013-06-11T15:26:50.780 回答