[xsl] Brain Teaser

Subject: [xsl] Brain Teaser
From: "Owens, Stephen P" <Stephen.P.Owens@xxxxxxxxxx>
Date: Wed, 5 Sep 2007 14:54:02 -0400
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