Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Closest Ancestor Matching Condition

Closest Ancestor Matching Condition

Scheduled Pinned Locked Moved Clever Code
xmlcsharpcomquestion
1 Posts 1 Posters 4 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AspDotNetDev
    wrote on last edited by
    #1

    XSLT sometimes makes me think outside of my normal thought process. Assuming the order of nodes is not deterministic, I couldn't think of a simple way to get the first ancestor node (inclusive of the current node) matching a certain condition. "First", in this case, meaning the most deeply descended node. So, I decided to get the node from the set of ancestors for which there did not exist an ancestor in that same node set which matched the node.

    <!-- Get ancestors and self. -->
    <xsl:for-each select="$currentPage/ancestor-or-self::*/*[local-name() = $propertyName]/parent::*">

    <!-- Remember the ID of the current node. -->
    <xsl:variable name="currentId" select="./@id" />

    <!-- Does the current node exist in the ancestors of the above result set? -->
    <xsl:if test="count($currentPage/ancestor-or-self::*/*[local-name() = $propertyName]/parent::*/ancestor::*[@id=$currentId]) = 0">

    <!-- We've found the closest ancestor matching the condition. -->
    <xsl:value-of select="local-name(.)" />
    

    </xsl:if>

    </xsl:for-each>

    If this were C#, I'd just use a while loop:

    while(node != null && !node.HasProperty(propertyName))
    {
    node = node.Parent;
    }

    I could have also created a recursive XSLT function to do something similar, but function calls in XSLT are so verbose that it wouldn't be worth it in this case. XSLT and LISP are two languages which always manage to get me really thinking (that could be seen as a good or a bad thing). :)

    [Forum Guidelines]

    1 Reply Last reply
    0
    Reply
    • Reply as topic
    Log in to reply
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes


    • Login

    • Don't have an account? Register

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • World
    • Users
    • Groups