[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: pruning nodes not in xpath list

Subject: Re: pruning nodes not in xpath list
From: "Cliff McBride" <cliff.mcbride@xxxxxxxxxxxxxx>
Date: Wed, 28 Feb 2001 17:07:08 -0800
cliff mcbride
Jeni,

Thanks a million!!!  I'm not sure I would have ever thought of using
"count(.|$selected-nodes) = $nselected-nodes" to test if the context
node is in the list of selected nodes.  Looks like I need to keep
reading the books and experimenting.

Thanks again,
Cliff

----- Original Message -----
From: "Jeni Tennison" <mail@xxxxxxxxxxxxxxxx>
To: "Cliff McBride" <cliff.mcbride@xxxxxxxxxxxxxx>
Cc: <XSL-List@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Wednesday, February 28, 2001 1:38 AM
Subject: Re:  pruning nodes not in xpath list


> Hi Cliff,
>
> > I would like to be able to generate a sytlesheet that will produce
> > output documents that exclude all nodes that are not matched by any
> > of the xpath expressions.
>
> The first thing is to work out a stylesheet that does what you want
> with the expressions hard-coded into it...
>
> > From an algorithm point of view, one solution is to create a
> > node-set collection of all nodes that should be copied to the output
> > document. For each xpath, find the terminal nodes and add them and
> > all of their ancestor elements to the node-set collection. After the
> > node-set collection is created, visit each node in source tree in
> > document order -- if the node exists in the node-set, use
> > <xsl:copy/>. This would ensure that each node only gets copied once,
> > and in the document-order so the tree is maintained. I cannot figure
> > out a way to implement this algorithm using XSLT. This could be done
> > with a DOM (Document), but I don't want to have to implement all of
> > the code to handle "xpath" expressions.
>
> OK, so first work out which nodes have been selected by the
> expressions:
>
> <xsl:variable name="selected-nodes"
>               select="//product/@sku | //product/cost"/>
>
> Then to work out which nodes should therefore be copied - that's all
> those nodes that are selected, plus their ancestors:
>
> <xsl:variable name="copied-nodes"
>               select="$selected-nodes | $selected-nodes/ancestor::*"/>
>
> Now, starting from the top (the document element is always the first
> in the list of copied nodes), we want to work through the document. If
> the element is in the list of selected nodes, then we just want to
> copy it completely. Otherwise, we want to copy the element, copy any
> attributes that are in the list of selected nodes, and apply templates
> to any of its children that are in the list of nodes to be copied.
>
> Now, working out whether a node is in a set of nodes involves a bit of
> set manipulation - if you count how many nodes there are in the set
> that's the union of the node and the node set, and it's the same as
> the number of nodes in the node set, then the node has to be in the
> node set.  So to work out whether the context node is in the set of
> $selected-nodes, I can use:
>
>   count(.|$selected-nodes) = count($selected-nodes)
>
> Since $selected-nodes and $copied-nodes are known up front, I'll
> create variables that indicate how many nodes are in each of them:
>
> <xsl:variable name="nselected-nodes" select="count($selected-nodes)"
/>
> <xsl:variable name="ncopied-nodes" select="count($copied-nodes)"/>
>
> So the template looks like:
>
> <xsl:template match="*">
>    <xsl:choose>
>       <!-- this node is one of the selected nodes -->
>       <xsl:when test="count(.|$selected-nodes) = $nselected-nodes">
>          <xsl:copy-of select="."/>
>       </xsl:when>
>       <xsl:otherwise>
>          <xsl:copy>
>             <!-- copy attributes that are selected nodes -->
>             <xsl:copy-of select="@*[count(.|$selected-nodes) =
>                                     $nselected-nodes]"/>
>             <!-- apply templates to nodes that are to be copied -->
>             <xsl:apply-templates select="node()[count(.|$copied-nodes)
=
>                                                 $ncopied-nodes]"/>
>          </xsl:copy>
>       </xsl:otherwise>
>    </xsl:choose>
> </xsl:template>
>
> And there you have it.  That stylesheet will take the input you
> specified and give the output you specified.
>
> Now all you have to do is create a stylesheet that creates it.  In
> fact most of it is static, so you could bundle it out to a separate
> stylesheet and include it rather than create it dynamically.  The only
> thing that isn't static is the creation of the $selected-nodes
> variable:
>
> <xsl:variable name="selected-nodes"
>               select="//product/@sku | //product/cost"/>
>
> Assuming that you're using oxsl as the namespace prefix for your XSLT
> namespace alias, then you need to create an oxsl:variable with a name
> attribute equal to selected-nodes:
>
> <oxsl:variable name="selected-nodes">
>    ...
> </oxsl:variable>
>
> The select attribute is created dynamically by iterating over the
> various expressions that you have (I'll assume their held in an $exprs
> variable):
>
> <oxsl:variable name="selected-nodes">
>    <xsl:attribute name="select">
>       <xsl:for-each select="$exprs">
>          <xsl:value-of select="." />
>          <xsl:if test="position() != last()"> | </xsl:if>
>       </xsl:for-each>
>    </xsl:attribute>
> </oxsl:variable>
>
> You should be able to create the rest of the stylesheet very
> straight-forwardly.
>
> I hope that helps,
>
> Jeni
>
> ---
> Jeni Tennison
> http://www.jenitennison.com/
>
>


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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.