Copied to clipboard

Flag this post as spam?

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


  • Dirk De Grave 4537 posts 6006 karma points MVP 3x admin c-trib
    Jun 17, 2013 @ 11:47
    Dirk De Grave
    0

    Combining 2 xpath axes

    Hi,

    Might a simple questions to those xslt gurus out there, just checking if it is possible at all. Currently having a site with quite a large number of nodes (+10k), so travelling the content tree can become quite slow using the DynamicNode/IPublishedContent extension methods Descendants()...

    Because of slow performance of these methods, I'm reverting to using plain old xslt to fetch the nodes I need to work with (XPath() is also available as extension method). Here's what nodes I'm trying to fetch:

    Content tree has following structure (not repeating top level 'Content' node)

    - Site
    -- Homepage
    --- Theme 1
    ---- Theme 1-1
    --- Theme 2
    ---- Theme 2-1
    ----- Category 2-1-1
    ------ Category 2-1-1-1

    I guess you get the point. There's a max of 2 'Theme' levels and a max of 2 'Category' levels

    Fetching nodes using xpath expression: .//*[@level > {0} and @level <= {1} and ./hideFromNavigation != '1'] takes about 450msec ({0} and {1} is replaced with level info for Theme and Category nodes). Last condition is only available on Theme/Category nodes, so we could rewrite the xpath expression to only include the last condition which improves performance significantly (Taking it down to 300msec)

    Here comes the good part. If I split up my xpath expression into several ones, not using the "//" axe, such as

    /root/Site/Home[@id={0}]/Theme[hideFromNavigation != '1'] (1 msec)
    /root/Site/Home[@id={0}]/Theme[hideFromNavigation != '1']/Theme[hideFromNavigation != '1'] (4 msec)
    /root/Site/Home[@id={0}]/Theme[hideFromNavigation != '1']/Theme[hideFromNavigation != '1']/Category[hideFromNavigation != '1'] (62 msec) and
    /root/Site/Home[@id={0}]/Theme[hideFromNavigation != '1']/Theme[hideFromNavigation != '1']/Category[hideFromNavigation != '1']/Category[hideFromNavigation != '1'] (44 msec)

    I was able to again improve performance drastically (Total = 100 msec)

    Question is:

    * Can I combine those into a single xpath expression (So I could get away with a single statement instead of 4)
    * Why would the last statement have better performance than the 3rd one (Even tho it has to query more nodes)

    Looking forward to any answers...

     

    Cheers,

    /Dirk

     

     

  • Chriztian Steinmeier 2726 posts 8320 karma points MVP 4x admin c-trib
    Jun 17, 2013 @ 12:20
    Chriztian Steinmeier
    1

    Hi Dirk,

    First off, I am sure you can optimize that by using XSLT keys - e.g. here's a previous post that was helpful in that regard.

    I'm not sure I understand what you mean by combining the 4 expressions into one? What's the final set of nodes you're looking for?

    The fact that the 4th is quicker than the 3rd - could it maybe just be that the fetched data from the 3rd is cached and reused? XSLT Processors are doing a lot of optimising, so it may also be that the fact that the path is more specific (thus eliminating more nodes from being searched) makes it perform faster...

    /Chriztian

  • Dirk De Grave 4537 posts 6006 karma points MVP 3x admin c-trib
    Jun 17, 2013 @ 13:27
    Dirk De Grave
    0

    well, i need both theme docs at level X and theme docs at level X+1 without using the "//" axis, as this hurts performance. I'm sure the "//" axis is designed to do such task, but it's much slower compared to executing 2 xpath queries against the same start node

    i don't think i can use the key stuff in c#, can i?

    /Dirk

  • Dirk De Grave 4537 posts 6006 karma points MVP 3x admin c-trib
    Jun 17, 2013 @ 13:28
    Dirk De Grave
    0

    Oh, and same goes for 'Categories' docs, which are at level X+2 and X+3 (X taken from previous post)

     

    /Dirk

  • Chriztian Steinmeier 2726 posts 8320 karma points MVP 4x admin c-trib
    Jun 17, 2013 @ 13:50
    Chriztian Steinmeier
    0

    Hi Dirk,

    Well, I guess there probably is a way to use keys in C# too - Lee Kelleher would probably know where to look, since he's done stuff including the XsltContext (?) before...

    In plain XSLT, I would at least cache the results of each, e.g:

    <xsl:variable name="rootID" select="1234" />
    
    <xsl:variable name="siteRoot" select="umbraco.library:GetXmlNodeById($rootID)" />
    
    <xsl:variable name="themes1"     select="$siteRoot/Theme[not(hideFromNavigation = 1)]" />
    <xsl:variable name="themes2"     select="$themes1/Theme[not(hideFromNavigation = 1)]" />
    <xsl:variable name="categories1" select="$themes2/Category[not(hideFromNavigation = 1)]" />
    <xsl:variable name="categories2" select="$categories1/Category[not(hideFromNavigation = 1)]" />

    Using keys, I'd index them by level since that's what you're using to retrieve them, something like:

    <xsl:key name="themesByLevel" match="Theme[not(hideFromNavigation = 1)]" use="@level" />
    <xsl:key name="categoriesByLevel" match="Category[not(hideFromNavigation = 1)]" use="@level" />
    
    <xsl:variable name="X" select="2" />
    
    <xsl:variable name="themes1"     select="key('themesByLevel', $X)" />
    <xsl:variable name="themes2"     select="key('themesByLevel', $X + 1)" />
    <xsl:variable name="categories1" select="key('categoriesByLevel', $X + 2)" />
    <xsl:variable name="categories2" select="key('categoriesByLevel', $X + 3)" />

    Hope we're getting closer to a solution for you,

    /Chriztian

     

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies