Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Elad Lachmi 112 posts 144 karma points
    May 01, 2011 @ 08:05
    Elad Lachmi
    0

    Writing more efficient XSLT

    Hi,

    In the last few weeks I was getting to know XSLT a little and getting some things done.

    I have several macros going in my site and everything is working well.

    After looking my XSLT code over a few times, I think I might not be writing the most efficient XSLT.

    I have the following code in a macro:

    <xsl:template match="/">

    <!-- start writing XSLT -->
    <ul class="faq-list">
    <xsl:for-each select="$currentPage//faq [@isDoc]">
    <li class="question-link"><a href="#" onclick="scrollAnswer({position()})"><xsl:value-of select="question" /></a></li>
    </xsl:for-each>
    </ul>

    <div class="faq-wrapper" style="margin-top: 40px;">
    <xsl:for-each select="$currentPage//faq [@isDoc]">
    <h2 id="answer_{position()}" class="question"><xsl:value-of select="question" /></h2>
    <span class="go_to_top" style="cursor: pointer; float:left; position:relative; top: 5px;"><img src="/images/up.png" /></span><div id="answer_{position()}_text" class="answer"><xsl:value-of select="answer" /></div>
    </xsl:for-each>
    </div>
    </xsl:template>

    My question is this: If I know that all the faq nodes will be children of the faqs node,

    how can I limit my search to only children of the faqs node?

    Currently it looks to me like I'm scanning the entire tree, and that seems a real waste.\

    Thank you!

  • Kim Andersen 1447 posts 2196 karma points MVP
    May 01, 2011 @ 10:25
    Kim Andersen
    2

    Hi Elad

    If you know that you only ned to run through the childnodes of the current page, you can change this:

    $currentPage//faq [@isDoc]

    to this:

    $currentPage/faq[@isDoc]

    By only adding one slash you are only running through the childnodes of the current page. When you are using two slashes, you are running throuhg all nodes below the current node. Was this what you where after?

    /Kim A

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    May 01, 2011 @ 18:03
    Lee Kelleher
    3

    Hi Elad,

    As Kim says by removing the extra slash will prevent the XPath from returning all desendent "faq" nodes - only the direct child nodes. Performance will already be much better.

    If you are looking for other best practices in XSLT, you could look at moving the <xsl:for-each> loops into their own <xsl:template>?

    Like so...

    <xsl:template match="/">
        <xsl:if test="$currentPage/faq[@isDoc]">
            <ul class="faq-list">
                <xsl:apply-templates select="$currentPage/faq[@isDoc]" mode="question" />
            </ul>
            <div class="faq-wrapper" style="margin-top:40px;">
                <xsl:apply-templates select="$currentPage/faq[@isDoc]" mode="answer" />
            </div>
        </xsl:if>
    </xsl:template>
    
    <xsl:template match="faq[@isDoc]" mode="question">
        <li class="question-link">
            <a href="#answer_{position()}" onclick="javascript:scrollAnswer({position()});">
                <xsl:value-of select="question" />
            </a>
        </li>
    </xsl:template>
    
    <xsl:template match="faq[@isDoc]" mode="answer">
        <h2 id="answer_{position()}" class="question">
            <xsl:value-of select="question" />
        </h2>
        <span class="go_to_top" style="cursor:pointer;float:left;position:relative;top:5px;">
            <img src="/images/up.png" />
        </span>
        <div id="answer_{position()}_text" class="answer">
            <xsl:value-of select="answer" />
        </div>
    </xsl:template>

    I think this way gives you better separation of the mark-up... but I'll let you decide what suits you best.

    Cheers, Lee.

  • Eran Meir 401 posts 543 karma points
    May 02, 2011 @ 08:36
    Eran Meir
    0

    is there really a diffrence in performence using templates?

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    May 03, 2011 @ 11:49
    Lee Kelleher
    1

    Hi Eran,

    My opinion is that it depends on how many nodes you need to iterate through - XSLT is optimised towards the use of templates. But say for a couple of hundred nodes, you probably wouldn't notice any performance issues.

    <xsl:for-each> vs <xsl:apply-templates> vs <xsl:call-template> ... they are mostly down to each developer's coding style. Jeni Tennison has a great blog post about her "Rules of thumb" for each approach.

    Personally I take the <xsl:template> approach as I may (at some point) might need to re-use the code block.

    Cheers, Lee.

Please Sign in or register to post replies

Write your reply to:

Draft