xsl-list
[Top] [All Lists]

RE: [xsl] Brain Teaser

2007-09-17 02:10:32
Hi,

How about this? You repeat over all type attributes, rebuild the ancestor tree 
for each of them, and recurse untill the next type attribute. In (pseudo) code 
something like this:

<template match="root">
        <copy>
                <for-each select="//*[(_at_)type]">
                        <apply-templates select="." mode="build-type" />
                </for-each>
        </copy>
</template>

<template match="*" mode="build-type">
        <type name="{(_at_)type}">
                <apply-templates select="." mode="rebuild-tree">
                        <with-param name="ancestors" 
select="ancestor::*[not(self::root)]" />
                </apply-templates>
        </type>
</template>

<template match="*" mode="rebuild-tree">
        <param name="ancestors" />
        <choose>
        <when test="count($ancestors) > 0">
                <element name="{name($ancestors[1])}">
                        <copy-of select="$ancetors[1]/@*" />
                        <attribute name="tag-id"><value-of 
select="generate-id()"/></attribute>
                        <apply-templates select="." mode="rebuild-tree">
                                <parameter name="ancestors" 
select="$ancestors[position() > 1]" />
                        </apply-templates>
                </element>
        </when>
        <otherwise>
                <copy>
                        <copy-of select="@*" />
                        <attribute name="tag-id"><value-of 
select="generate-id()"/></attribute>
                        <apply-templates select="*" mode="recurse" />
                </copy>
        </otherwise>
        </choose>
</template>

<template match="*[(_at_)type]" mode="recurse">
        <!-- terminate recursion when next @type is discovered -->
</template>

<template match="*" mode="recurse">
        <copy>
                <copy-of select="@*" />
                <attribute name="tag-id"><value-of 
select="generate-id()"/></attribute>
                <apply-templates select="*" mode="recurse" />
        </copy>
</template>

Note: this DOES require that all important content parts are wrapped in 
elements with a type attribute, otherwise those will get lost..

Kind regards,
Geert


   
 
Drs. G.P.H. Josten
Consultant
 
 

Daidalos BV
Source of Innovation
Hoekeindsehof 1-4
2665  JZ  Bleiswijk
Tel.: +31 (0) 10 850 1200
Fax: +31 (0) 10 850 1199
www.daidalos.nl
KvK 27164984


De informatie - verzonden in of met dit emailbericht - is afkomstig van 
Daidalos BV en is uitsluitend bestemd voor de geadresseerde. Indien u dit 
bericht onbedoeld hebt ontvangen, verzoeken wij u het te verwijderen. Aan dit 
bericht kunnen geen rechten worden ontleend.
 

From: Owens, Stephen P 
[mailto:Stephen(_dot_)P(_dot_)Owens(_at_)pfizer(_dot_)com] 
Sent: woensdag 5 september 2007 20:54
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Cc: Parnell, Ryan A
Subject: [xsl] Brain Teaser

I have a problem in XSLT that I simply do not know how to solve. 

Perhaps someone smarter than me can show their stuff.

Suppose you have a document such as the following:

<root>
   <section type="foo">
      <a>Text 1</a>
      <a type="bar">Mixed Content
         <b type="foo">Text 2</b>
         <b>Mixed Content
              <c>Text 3</c>
              <c type="bar">Text 4</c>
         </b>
      </a>
   </section>
</root>

The root tag can contain any number of section type tags.  
Section and single letter tags a-z support the type attribute 
which can be any string value.
Further suppose that the schema allows section tags to 
contain any single letter tag a-z. Also any single letter tag 
a-z may contain any combination and number of single letter 
tags a-z. All single letter tags support mixed content as well.

How is it possible using XSLT to convert the document to one 
such as the following.

<root>
   <type name="foo">
      <section type="foo" tag-id="001">
         <a tag-id="002">Text 1</a>
      </section>
   </type>
   <type name="bar">
      <section tag-cont="001">
         <a tag-cont="002">
            <b tag-id="003">Text 2</b>
            <b tag-id="004">Mixed Content
                <c>Text 3</c>
            </b>
         </a>
      </section>
   </type>
   <type name="foo">
      <section tag-cont="001">
         <a tag-cont="002">
            <b tag-cont="004">
                <c tag-id="005">Text 4</c>
            </b>
         </a>
      </section>
   </type>
</root>

The idea is that wherever a tag appears with a type attribute 
in the source document, that tag and the tags that follow 
appear in a well formed structure wrapped by a "type" tag in 
the target document, thus whenever a new type attribute is 
encountered on a tag, we close everything up to a 
pre-determined certain stopping point somewhere before the 
top such as the child of root in this case, and then we 
re-open duplicates of everything, and continue on with the processing.

Examining the above source and target example should give you 
a clearer idea.  Also, for anything we re-open from the 
previous we tie to the previous as a continuation by adding 
an tag-id attribute to the original tag, and a tag-cont 
attribute to the subsequent continuation.

I think it is fairly trivial to write a transform that goes 
from the latter to the former, but I can think of no way to 
go from the former to the latter. 

For those of you thinking this is a trivial exercise consider 
the real world application of translating DocBook XML or 
similar schemas into XSL-FO.

Anyone out there up for a challenge?


----------------------------------------------------------------------
LEGAL NOTICE
Unless expressly stated otherwise, this message is 
confidential and may be privileged.  It is intended for the 
addressee(s) only.  Access to this E-mail by anyone else is 
unauthorized.  If you are not an addressee, any disclosure or 
copying of the contents of this E-mail or any action taken 
(or not taken) in reliance on it is unauthorized and may be 
unlawful.  If you are not an addressee, please inform the 
sender immediately.

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

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