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 |