xsl-list
[Top] [All Lists]

[xsl] use generate-id and keys to make a transform more efficient

2012-03-06 23:58:06
Hi,

I have the following that I'm currently working on and am sure that it can be 
improved upon.  I've got Michael Kay's book and have been through Dave Pawson's 
site many times, but can't figure our how to apply their advice to my specific 
tranform.

Anyway, I'm limited to pure XSLT (no extension functions), v1.0 only.  No 
option to change the input xml nor upgrade to XSLT v2.0 either unfortunately.

Here are the contents of my files:

input.xml:
<entries>
  <entry>
    <qqqq>
      <id>1111</id>
    </qqqq>
  </entry>
  <entry>
    <startLoop>
      <loopId>1</loopId>
    </startLoop>
  </entry>
  <entry>
    <qqqq>
      <id>2222</id>
    </qqqq>
  </entry>
  <entry>
    <endLoop>
      <loopId>1</loopId>
    </endLoop>
  </entry>
  <entry>
    <qqqq>
      <id>3333</id>
    </qqqq>
  </entry>
  <entry>
    <startLoop>
      <loopId>2</loopId>
    </startLoop>
  </entry>
  <entry>
    <endLoop>
      <loopId>2</loopId>
    </endLoop>
  </entry>
  <entry>
    <qqqq>
      <id>4444</id>
    </qqqq>
  </entry>
</entries>


output.xml:
<AAA>
  <SEQUENCE>
    <outputEntry>
      <entry>
        <qqqq>
          <id>1111</id>
        </qqqq>
      </entry>
    </outputEntry>
    <outputEntry>
      <entry>
        <startLoop>
          <loopId>1</loopId>
        </startLoop>
      </entry>
    </outputEntry>
    <outputEntry>
      <entry>
        <qqqq>
          <id>3333</id>
        </qqqq>
      </entry>
    </outputEntry>
    <outputEntry>
      <entry>
        <startLoop>
          <loopId>2</loopId>
        </startLoop>
      </entry>
    </outputEntry>
    <outputEntry>
      <entry>
        <qqqq>
          <id>4444</id>
        </qqqq>
      </entry>
    </outputEntry>
  </SEQUENCE>

  <LOOPS>
    <LOOP>
      <STARTLOOP>
        <entry>
          <startLoop>
            <loopId>1</loopId>
          </startLoop>
        </entry>
      </STARTLOOP>
      <MIDDLE>
        <entry>
          <qqqq>
            <id>2222</id>
          </qqqq>
        </entry>
      </MIDDLE>
      <ENDLOOP>
        <entry>
          <endLoop>
            <loopId>1</loopId>
          </endLoop>
        </entry>
      </ENDLOOP>
    </LOOP>

    <LOOP>
      <STARTLOOP>
        <entry>
          <startLoop>
            <loopId>2</loopId>
          </startLoop>
        </entry>
      </STARTLOOP>
      <ENDLOOP>
        <entry>
          <endLoop>
            <loopId>2</loopId>
          </endLoop>
        </entry>
      </ENDLOOP>
    </LOOP>
  </LOOPS>
</AAA>



XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
exclude-result-prefixes="xsl">
  <xsl:output method="xml" omit-xml-declaration="yes"/>

  <xsl:template match="/entries">
    <AAA>   
      <!-- first, output sequence without loop contents -->
      <SEQUENCE>
        <xsl:for-each select="entry">
          <xsl:choose>
            <xsl:when test="not(preceding-sibling::entry[startLoop]) or 
preceding-sibling::entry[endLoop] and not(./endLoop)">
              <outputEntry>
                <xsl:copy-of select="."/>
              </outputEntry>
            </xsl:when>
          </xsl:choose>
        </xsl:for-each>
      </SEQUENCE>
      
      <!-- second, output each loop sequence contents -->
      <LOOPS>
        <xsl:for-each select="entry">
          <xsl:if test="./startLoop">
            <LOOP>
              <xsl:variable name="start" select="count(preceding-sibling::*) + 
1"/>
              <xsl:variable name="end" select="$start + 
count(following-sibling::entry[endLoop])"/>
              <STARTLOOP>
                <xsl:copy-of select="."/>
              </STARTLOOP>
              <xsl:for-each select="/entries/entry[position() &gt; $start and 
position() &lt;= $end]">
                <xsl:choose>
                  <xsl:when test="./endLoop">
                    <ENDLOOP>
                      <xsl:copy-of select="."/>
                    </ENDLOOP>
                  </xsl:when>
                  <xsl:otherwise>
                    <MIDDLE>
                      <xsl:copy-of select="."/>
                    </MIDDLE>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:for-each>
            </LOOP>
          </xsl:if>
        </xsl:for-each>
      </LOOPS>
    </AAA>
  </xsl:template>

</xsl:stylesheet>



Thanks for any advice,
Michael.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>