xsl-list
[Top] [All Lists]

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

2007-06-24 22:16:07
This post refers to a question I posed back on April 19th and the suggested
transformations that Michael Kay and Ken Holman generously provided.

Michael provided two slightly different solutions to cover some ambiguity in
my
question.  When I run his solutions, however, I get different results than I
expected and wonder if I am implementing them incorrectly or if my statement
of the problem was unclear.  I have since revised the summary of the problem
for hopefully better clarity and also edited the data file to remove what I
believe are redundant attributes.

I'm hoping to try and resolve why I can't get Michael's solutions to work.

Simon

**************************************************************************
Summary of Problem
**************************************************************************
(thanks to Trevor Nicholls and Ragulf Pickaxe back in April for their help)

There is a structure tree (in.xml) and a data tree (data.xml) - see examples
below.  The structure tree is fixed and complete.  The data tree is variable
and may contain any element which corresponds to a descendant-less node
(leaf node) in the structure tree (at most one of each element).

The desired output is a merge of the structure tree and the data tree,
where:
 a) for any specific leaf node in the structure tree:
   (i) if the data tree contains a matching node with @result=true
     then @complete=true and @result=true,
   (ii) if the data tree contains a matching node with @result=false
     then @complete=true and @result=false, and
   (iii) if the data tree does not contain a matching node
     then @complete=false and @result=true (because I do not want 
     to affect the logical AND value of ancestor nodes' @result value
     when they include leaf nodes with @complete=false - see b) (iii) below

 b) for every other internal node in the structure tree:
   (i) if the data tree contains a matching node for every leaf node in the
     structure tree (that is descendent of this internal node) and each
     matching node has @result=true then for this internal node
     @complete=true and @result=true,
   (ii) similarly, if the data tree contains a matching node for every leaf
     node in the structure tree but not all results are true then for this
     internal node @complete=true and @result=false,
   (iii) if the data tree does not contain a matching node for every leaf
     node in the structure tree but the value of each matching node that it
     does contain has @result=true then for the internal node
     @complete=false and @result=true,
   (iv) if the data tree does not contain a matching node for every leaf
     node in the structure tree and the value of any matching node that it
     does contain has @result=false then @complete=false and @result=false


**************************************************************************
Example structure tree (in.xml)
**************************************************************************
<a>
  <b>
    <c/>
    <d/>
  </b>
  <e>
    <f/>
    <g>
      <h/>
      <i/>
    </g>
  </e>
</a>

**************************************************************************
Example data tree (data.xml)
**************************************************************************
<data>
  <c result="true"/>
  <d result="false"/>
  <h result="true"/>
  <i result="true"/>
</data>

**************************************************************************
Example desired result
**************************************************************************

<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="true"/>
    <g complete="true" result="true"/>
      <h complete="true" result="true"/>
      <i complete="true" result="true"/>
    </g>
  </e>
</a>

**************************************************************************
Michael's first stylesheet (mkay1.xsl)

Comments:
        - non-leaf nodes look at all descendants
**************************************************************************

<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>


**************************************************************************
Output I get from Michael's first stylesheet (mkay1.xml)

Comments:
        - node e should have result="true" because none of its descendent
        nodes have result="false"
        - not sure how $tree is used
**************************************************************************

<?xml version="1.0" encoding="UTF-8"?>
<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="false"> <!-- @result should be true -->
      <f complete="false" result=""/>
      <g complete="true" result="true">
         <h complete="true" result="true"/>
         <i complete="true" result="true"/>
      </g>
  </e>
</a>


**************************************************************************
Michael's second stylesheet (mkay2.xsl)

Comments:
        - non-leaf nodes should only look at leaf node descendants
**************************************************************************

<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 
                 (* 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>

  <!-- 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>


**************************************************************************
Output from Michael's second stylesheet (mkay2.xml)

Comments:
        - nodes a and b should have @result=false because node d has 
        @result=false
        - node e should have @complete=false because node f is missing from
        data.xml
        - not sure how $tree is used
**************************************************************************

<?xml version="1.0" encoding="UTF-8"?>
<a complete="true" result="true"> <!-- @result should be false -->
  <b complete="true" result="true"> <!-- @result should be false -->
      <c complete="true" result="true"/>
      <d complete="true" result="false"/>
  </b>
  <e complete="true" result="true"> <!-- @complete should be false -->
      <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>
--~--

<Prev in Thread] Current Thread [Next in Thread>
  • RE: [xsl] Constructing a tree from leaf nodes (knowing the tree structure)?, Simon Shutter <=