How can I convert the following XML to an escaped text using XSLT?
Source:
<?xml version="1.0" encoding="utf-8"?>
<abc>
<def ghi="jkl">
mnop
</def>
</abc>
Output:
<TestElement><?xml version="1.0" encoding="utf-8"?><abc><def ghi="jkl">
mnop
</def></abc></TestElement>
Currently, I'm trying the following XSLT and it doesn't seem to work properly:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="/">
<xsl:variable name="testVar">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:variable>
<TestElement>
<xsl:value-of select="$testVar"/>
</TestElement>
</xsl:template>
</xsl:stylesheet>
Output of XSLT statement by the .NET XslCompiledTransform comes out as the following:
<?xml version="1.0" encoding="utf-8"?><TestElement>
mnop
</TestElement>
I attempted to implement the answer provided by Pavel Minaev and want to point out that this is very dangerous for large strings as each character in the input string is recursed over individually, causing the recursion depth to quickly run out. I attempted to run it over a few lines of text and it caused a stack overflow (lol).
Instead, I use a template that does not need to examine each individual char, rather it will out put the text until it finds a string that needs to be replaced. This can then be used to escape characters:
Then its just a matter of calling that template for the char that you want to escape..
In order to escape multiple characters in the one string, I used a wrapper template that uses variables...
This proved to be much safer for large strings as it no longer has to recurse for each individual character in the input string.
You can prevent the extra namespace nodes by adding a test in the namespace output: