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

Selecting a tree...

Subject: Selecting a tree...
From: Klaus-Georg Adams <Klaus-Georg.Adams@xxxxxxx>
Date: Wed, 30 Jan 2002 11:31:29 +0100 (MET)
selecting a tree node
Hi,
I have an XML file which represents multiple trees like so:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE document [
<!ELEMENT document (node*)>
<!ELEMENT node (subnode*)>
<!ATTLIST node name NMTOKEN #REQUIRED
               isroot (true|false) "false">
<!ELEMENT subnode EMPTY>
<!ATTLIST subnode name NMTOKEN #REQUIRED>
]>
<document>
  <node name="root1" isroot="true">
    <subnode name="node1"/>
    <subnode name="node2"/>
  </node>
  <node name="root2" isroot="true">
  </node>
  <node name="node1">
    <subnode name="node3"/>
  </node>
  <node name="node2">
    <subnode name="node3"/>
  </node>
  <node name="node3"/>
</document>

A node can refer to subnodes by their name. Names are unique. There
can be multiple roots in the XML file. A node can be referenced
multiple times in any given tree.

I would like to write a stylesheet which gets as parameter a nodename
of a rootnode, and which spits out an XML file containing all nodes
referenced by the tree, but, and here's the catch: only once for each
node.

Thus, the transformation should remove root2 from the XML file above
if $rootnode is set to root1.

Following the tree and spitting out all nodes in that tree is easy:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="xml"
    indent="yes"/>

  <xsl:param name="rootnode"/>

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="document">
    <document>
      <xsl:apply-templates select="node[@name = $rootnode]" mode="follow"/>
    </document>
  </xsl:template>

  <xsl:template match="node" mode="follow">
    <xsl:apply-templates select="."/>
    <xsl:apply-templates select="//node[@name=current()/subnode/@name]" mode="follow"/>
  </xsl:template>

  <!-- identity transformation -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

But this will spit out nodes as often as they apear in the tree. Does
anybody see a way around this?

The only solution I can think of (in pure XSLT) would need two
transformations: the first would write an intermediate file with a
list of nodenames which have to appear in the final document (with
duplicates) and a second one, which would remove the duplicates and
write the real output file.

Is there a way to do it in one transformation?

Regards, kga


 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.