xsl-list
[Top] [All Lists]

following crosslinks

2003-10-21 04:56:20
Hello,

I'd like to prune all paths from the root
to leaves which are not descendants
of a given element.  The XML document
may contain crosslinks.

The following stylesheet does this assuming "d" is
the given element name.

<xsl:stylesheet>
<xsl:template match="node()[not
        (descendant-or-self::node()[ancestor-or-self::d and
                                    count (child::node()) = 0])]"/>
<xsl:template match="*|@*">
   <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
</xsl:template>
</xsl:stylesheet>

This stylesheet basically copies all nodes to the 
result tree, EXCEPT those NOT containing
a descendant which is an ancestor of one 
of the desired leaves (those which are
descendants of a "d").

Consider the following XML.

<db id="1">
   <a id="2">
      <d id="5">
         <g id="10"/>
         <h id="11"/>
      </d>
      <e id="6">
         <g refid="11"/>
         <h id="12"/>
      </e>
   </a>
   <b id="3">
      <f refid="5"/>
      <d id="7">
         <g id="13"/>
      </d>
   </b>
   <c id="4">
      <d id="8">
         <g id="14"/> 
      </d>
      <f id="9">
         <g id="15"/> 
         <h id="16"/> 
      </f>
   </c>
</db>

Running this doc. through the above stylesheet
produces the following.

<db id="1">
   <a id="2">
      <d id="5">
         <g id="10"/>
         <h id="11"/>
      </d>
   </a>
   <b id="3">
      <d id="7">
         <g id="13"/>
      </d>
   </b>
   <c id="4">
      <d id="8">
         <g id="14"/>
      </d>
   </c>
</db>

Notice that both crosslinks in the original
doc (e.g., <g refid="11"/> and <f refid="5"/>)
have been left out of the result tree, EVEN
THOUGH they each clearly have a descendant
which is an ancestor of one 
of the desired leaves (those indexed under a "d";
e.g., ids 10, 11, 13, and 14).  This is
because each is caught by that painful
match expression in the first template
above, since it DOESN'T follow refids.

Is there a crisp, clean, or elegant
modification to the above stylesheet
to follow the crosslinks (refids) and
include those in the result that
satisfy the property?
For example, the following 
is desired result tree.

<db id="1">
   <a id="2">
      <d id="5">
         <g id="10"/>
         <h id="11"/>
      </d>
      <e id="6">
         <g refid="11"/>
      </e>
   </a>
   <b id="3">
      <f refid="5"/>
      <d id="7">
         <g id="13"/>
      </d>
   </b>
   <c id="4">
      <d id="8">
         <g id="14"/> 
      </d>
   </c>
</db>

Notice that each path through this tree 
classifies a leaf node which
is a descendant of some "d".

Thank You and Best Regards,
Saverio

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



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