Reputation: 511
I am building some text snippets from XML documents using XSL transformation. The text can include '<' and '>' (and other special characters) in the output.
Given the following xml as data.xml
:
<SCH>
<Ship Id="1" Name="Dicke Bertha" OperatingCostsDay="10.0000000" currency="USD" />
</SCH>
and the following xsl as transformation.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
Schiff: <xsl:for-each select="SCH/Ship"> Id: <xsl:value-of select="@Id"/>  <xsl:value-of select="@Name"/>  (OC:<xsl:value-of select="@OperatingCostsDay"/> <xsl:value-of select="@currency"/>)
</xsl:for-each>Betriebskosten < 500 USD oder > 1 Mio. USD
</xsl:template>
</xsl:stylesheet>
I have the problem that the escape sequences <
and >
when loading the XSLT:
var xslDocument = XDocument.Load("transformation.xslt");
The output after the transformation is not - as expected - with the '<' and '>' characters but it has the HTML escape sequences.
Schiff: Id: 1 Dicke Bertha (OC:10.0000000 USD)
Betriebskosten < 500 USD oder > 1 Mio. USD
What can I do here?
For completeness, here is the full code example:
class Program
{
static void Main(string[] args)
{
var xslDocument = XDocument.Load("transformation.xslt");
var compiled = new XslCompiledTransform();
using (var reader = xslDocument.CreateReader())
{
compiled.Load(reader);
}
var xml = File.ReadAllText("data.xml");
Console.WriteLine(Transform(compiled, xml));
}
public static string Transform(XslCompiledTransform xsl, string xml)
{
// allow fragments
var writerSettings = new XmlWriterSettings { ConformanceLevel = ConformanceLevel.Auto };
var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Auto };
var stringReader = new StringReader(xml);
var details = new StringBuilder();
using (var reader = XmlReader.Create(stringReader, readerSettings))
{
using (var writer = XmlWriter.Create(details, writerSettings))
{
xsl.Transform(reader, writer);
}
}
return details.ToString();
}
}
Upvotes: 1
Views: 299
Reputation: 116959
I am building some text snippets
If you are outputting text, then set your output method to text
. Then your processor will know not to escape characters that are reserved in XML.
XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:template match="/">
Schiff: <xsl:for-each select="SCH/Ship"> Id: <xsl:value-of select="@Id"/>  <xsl:value-of select="@Name"/>  (OC:<xsl:value-of select="@OperatingCostsDay"/> <xsl:value-of select="@currency"/>)
</xsl:for-each>Betriebskosten < 500 USD oder > 1 Mio. USD
</xsl:template>
</xsl:stylesheet>
Result:
Schiff: Id: 1 Dicke Bertha (OC:10.0000000 USD)
Betriebskosten < 500 USD oder > 1 Mio. USD
Note also that literal text is best put inside xsl:text
instructions - otherwise you're passing all the unwanted surrounding whitespace to the output.
Upvotes: 2
Reputation: 1559
in XSLT, you can try like
Here I have added <xsl:text disable-output-escaping="yes"><</xsl:text>
and <xsl:text disable-output-escaping="yes">></xsl:text>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
Schiff: <xsl:for-each select="SCH/Ship"> Id: <xsl:value-of select="@Id"/>  <xsl:value-of select="@Name"/>  (OC:<xsl:value-of select="@OperatingCostsDay"/> <xsl:value-of select="@currency"/>)
</xsl:for-each> Betriebskosten <xsl:text disable-output-escaping="yes"><</xsl:text> 500 USD oder <xsl:text disable-output-escaping="yes">></xsl:text> 1 Mio. USD
</xsl:template>
</xsl:stylesheet>
Upvotes: 1