xsl-list
[Top] [All Lists]

RE: [xsl] Constructing a tree from leaf nodes (knowing the tree structure)?

2007-04-20 00:49:44

OK, so you have two rules, one for leaf nodes and one for non-leaf nodes.
Something like this:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output indent="yes"/>

<xsl:variable name="tree" select="/"/>
<xsl:variable name="data" select="doc('data.xml')/data"/>

<!-- rule for non-leaf nodes -->

<xsl:template match="*[*]">
  <xsl:copy>
    <xsl:attribute name="complete" 
       select="every $n in descendant::* satisfies 
                 exists($data/*[name() = name($n)])"/>
    <xsl:attribute name="result"
           select="every $n in descendant::* satisfies 
                 exists($data/*[name() = name($n) and @result='true']) "/>
    <xsl:apply-templates/>             
  </xsl:copy>
</xsl:template>

<!-- rule for leaf nodes -->

<xsl:template match="*">
  <xsl:copy>
    <xsl:attribute name="complete" 
       select="exists($data/*[name() = name(current())])"/>
    <xsl:attribute name="result"
           select="$data/*[name() = name(current())]/@result"/>
    <xsl:apply-templates/>             
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

This actually gives the right answer, but it's possible that the rule for
non-leaf nodes should only look at leaf descendants, not at all descendants,
which would change it to:

<xsl:template match="*[*]">
  <xsl:copy>
    <xsl:attribute name="complete" 
       select="every $n in descendant::* satisfies 
                 (* or exists($data/*[name() = name($n)]))"/>
    <xsl:attribute name="result"
           select="every $n in descendant::* satisfies 
                 (* or exists($data/*[name() = name($n) and
@result='true']))"/>
    <xsl:apply-templates/>             
  </xsl:copy>
</xsl:template>

Michael Kay
http://www.saxonica.com/

Thanks, Michael.

The "complete" attribute signifies whether all required 
descendent nodes are present or not.  For a leaf node I 
assume that if it is present complete="true" and if it is 
absent complete="false".  Hence f has complete="false".  I 
agree it is redundant for the data elements c,d,h and i to 
have complete="true" but I need the attribute to be present 
to that I can style the tree in HTML.

As far as the ancestors go, b is complete because all its 
descendants are complete, while e and a are incomplete 
because some of their descendants are incomplete.

Simon


-----Original Message-----
From: Michael Kay [mailto:mike(_at_)saxonica(_dot_)com]
Sent: April 19, 2007 4:14 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: RE: [xsl] Constructing a tree from leaf nodes 
(knowing the tree structure)?

XSLT is certainly suited to the problem. However, I can't 
reverse engineer your requirements from your example. The 
following stylesheet comes close, and there are various ways 
I could refine it to produce your required output, but I'd be 
using guesswork as to what the requirements are, so it would 
be better if you do that yourself! In particular I can't see 
why you consider b to be complete while f is incomplete, and 
since all the data elements say complete="true", it's hard to 
see what role that attribute plays in the calculation.

I used your tree as the principal input, and wrapped the 
other nodes in a <data> element and called it data.xml. The 
stylesheet is:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output indent="yes"/>

<xsl:variable name="tree" select="/"/>
<xsl:variable name="data" select="doc('data.xml')/data"/>

<xsl:template match="*">
  <xsl:copy>
    <xsl:attribute name="complete" 
       select="every $n in descendant::* satisfies 
                 exists($data/*[name() = name($n)])"/>
    <xsl:attribute name="result"
           select="every $n in descendant::* satisfies 
                 exists($data/*[name() = name($n) and 
@result='true']) "/>
    <xsl:apply-templates/>             
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>         

Michael Kay
http://www.saxonica.com/ 

-----Original Message-----
From: Simon Shutter [mailto:simon(_at_)schemax(_dot_)com]
Sent: 19 April 2007 21:02
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Constructing a tree from leaf nodes (knowing 
the tree 
structure)?

This is probably a poorly posed question but essentially I 
am trying 
to determine if XSLT is suited to the following problem.

Say I have a node fragment that defines a tree structure in 
which each 
element appears only once eg.

<a>
  <b>
    <c/>
    <d/>
  </b>
  <e>
    <f/>
    <g>
      <h/>
    <i/>
    </g>
  </e>
</a>

I then have data for some of the leaf nodes ie.

<c complete="true" result="true"/>
<d complete="true" result="false"/>
<h complete="true" result="true"/>
<i complete="true" result="true"/>

In this example the leaf node </f> is missing.

Is it possible to create a node fragment that mimics the tree 
structure and sets ancestor attributes according to the presence or 
absence of leaf nodes and their attributes?

The desired output would be:

<a complete="false" result="false">
  <b complete="true" result="false">
    <c complete="true" result="true"/>
    <d complete="true" result="false"/>
  </b>
  <e complete="false" result="true"> 
    <f complete="false" result=""/>
    <g complete="true" result="true"/>
      <h complete="true" result="true"/>
      <i complete="true" result="true"/>
    </g>
  </e>
</a>




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--