0

In XSLT, how do you select/copy part of the document as text only?

The change I want to make is to take part of the tree (tags and values both) and output it as text only (preferably with brackets HTML-encoded).

I tried to put a CDATA around my copy-of, but it simply put the copy-of command inside my document.

Edit: See comment below

Eric
  • 786
  • 1
  • 9
  • 16
  • You really should explain what you are trying to do with this. Explain the problem, not the alleged solution. – Tomalak Nov 17 '09 at 10:16
  • I have to maintain compatibility with a legacy application which does the same thing -- takes some part of the tree of a document and outputs it as text only -- with the brackets of the tags HTML-encoded like so: <firstTagAsText><BR> – Eric Nov 17 '09 at 13:14
  • Have you considered sending a hitman after the person who designed this legacy application? Not that it would solve your immediate problem, but that would be a service to us all. – ddaa Nov 17 '09 at 17:29

2 Answers2

1

Try this, but note that it won't handle nested CDATA correctly:

<xsl:text disable-output-escaping="yes">&lt;</xsl:text>
<xsl:text>![CDATA[</xsl:text>

<xsl:copy-of select="..." />

<xsl:text>]]</xsl:text>
<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • On reflexion, that might work in a sick sort of way. But too late to remove downvote. – ddaa Nov 16 '09 at 23:42
  • It will work so long as processor supports disabling output escaping (which is non mandatory). I wasn't quite correct about the severity of the problem with nested CDATA, too - in XSLT 1.0, a processor can never _output_ CDATA (even if input had CDATA) - it has to escape using character entities instead, except if `cdata-section-elements` is used to tell it to do otherwise. – Pavel Minaev Nov 16 '09 at 23:47
  • Well, that's an interesting stunt. This sort of things are liable to summon the Dark One, but the alternative would be insanely complex. – ddaa Nov 16 '09 at 23:54
  • This solution might produce a subtle problem with processing the translation's result. Please see my comment [here](http://stackoverflow.com/a/2265933/720999). – kostix Mar 22 '16 at 15:11
1

That's a strange requirement.

Since XSLT works on a parsed document model, you cannot do this reliably. In particular, the distinction between equivalent notations will necessarily be lost. Equivalent notations include things like <tag></tag> versus <tag/>, or &eacute; versus é.

That said, a general approach that might work would be using the mode attribute of xsl:template and xsl:apply-template to switch to a mode that explicitly render all elements as text. In effect you would be writing a XML serializer in XSLT.

One issue though is that you would have to double-escape special characters such as <>"' when present in attribute values and text nodes. And XSLT is quite inefficient at this sort of string munging.

Another issue would be rendering namespace prefixes reasonably. You can almost certainly do it, but that be quite horrible.

ddaa
  • 52,890
  • 7
  • 50
  • 59