| 
 
Subject: RE: [xsl] Brain Teaser From: "Geert Josten" <geert.josten@xxxxxxxxxxx> Date: Mon, 17 Sep 2007 11:10:23 +0200  | 
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="//*[@type]">
			<apply-templates select="." mode="build-type" />
		</for-each>
	</copy>
</template>
<template match="*" mode="build-type">
	<type name="{@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="*[@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.P.Owens@xxxxxxxxxx]
> Sent: woensdag 5 september 2007 20:54
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 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.
| Current Thread | 
|---|
  | 
| <- Previous | Index | Next -> | 
|---|---|---|
| Re: [xsl] Brain Teaser, Ronan Klyne | Thread | Re: [xsl] Brain Teaser, Eric Bréchemier | 
| Re: [xsl] Constructing multi-level , Andrew Welch | Date | Re: [xsl] Brain Teaser, Eric Bréchemier | 
| Month |