Re: [xsl] Fw: Select entire XML doc [FURTHER]

Subject: Re: [xsl] Fw: Select entire XML doc [FURTHER]
From: Mike Brown <mike@xxxxxxxx>
Date: Thu, 27 Feb 2003 19:44:35 -0700 (MST)
Karl Stubsjoen wrote:
> Further:
> I need to preserve the XML data as XML, so maybe change the output of the
> template to XML.  Is that possible?
> Thanks,
> Karl

Browsers are lenient when they encounter markup inside a textarea.
It is actually an error to do something like

  <textarea><someothertag>foo</someothertag></textarea>

which is what you are generating. You are supposed to generate

  <textarea>&lt;someothertag&gt;foo&lt;/someothertag&gt;</textarea>

Presumably you are outputting with the HTML output method. If your XML
contains any HTML elements in an empty namespace, you will find that they
will be output in HTML syntax, which means for example that <br/> will come
out as <br>, thus making your textarea contain non-well-formed XML, which
presumably is not what you want.

These two reasons are why you want to output your XML in serialized form. To
understand what we mean by "serialized form" you must first understand the
concept of a node tree (the DOM-like tree that XPath and XSLT uses) as being
the parsed, deserialized representation of an XML document, and you must
understand that your stylesheet only provides instructions for creating a new
node tree; the xsl:output instruction merely provides a hint to the processor
as to how you would prefer that new node tree to be serialized after it has
been constructed.

What you want to create in your node tree is (here in my best ASCII art):

  element 'textarea'
    |
    |___text '<lotsOfXml/>'

Understand that the serialized form of these two nodes when using the html
or xml output methods would be

  <textarea>&lt;lotsOfXml/&gt;</textarea>

which is what you want.

What you have done by using xsl:copy-of is created something like:

   element 'textarea'
     |
     |___element 'lotsOfXml'
            |
            |___element 'childOfLotsOfXml'
            :
            ...

In other words you took the whole source tree, sans the root node, and copied it
into the result tree as a child of the textarea element. This was then serialized
as

  <textarea><lotsOfXml><childOfLotsOfXml>...</childOfLotsOfXml></lotsOfXml></textarea>

and as I noted above, if you used html output method, any 'br' or 'hr' in your XML
would come out as <br> and <hr>.

What you should do is look into using either an extension function that serializes
the XML in an HTML character data safe way, or use a template that does the same thing.
Evan Lenz wrote a nice one at http://www.xmlportfolio.com/xml-to-string/

All you need to do is import it and then call the xml-to-string template, passing a
parameter named node-set, which is the set you want to serialize:

<xsl:import href="xml-to-string.xsl"/>

<xsl:template match="/">
  <textarea>
    <xsl:call-template name="xml-to-string">
      <xsl:with-param name="node-set" select="."/>
    </xsl:call-template>
  </textarea>
</xsl:template>

Mike

-- 
  Mike J. Brown   |  http://skew.org/~mike/resume/
  Denver, CO, USA |  http://skew.org/xml/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread