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