MiGro
MiGro

Reputation: 511

XSLT: Howto output '<' and '>' from XSL transformation?

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"/>&#160; <xsl:value-of select="@Name"/>&#160; (OC:<xsl:value-of select="@OperatingCostsDay"/>&#160;<xsl:value-of select="@currency"/>)
    </xsl:for-each>Betriebskosten &#60; 500 USD oder &#62; 1 Mio. USD
  </xsl:template>

</xsl:stylesheet>

I have the problem that the escape sequences &#60; and &#62; 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 &lt; 500 USD oder &gt; 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

Answers (2)

michael.hor257k
michael.hor257k

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"/>&#160; <xsl:value-of select="@Name"/>&#160; (OC:<xsl:value-of select="@OperatingCostsDay"/>&#160;<xsl:value-of select="@currency"/>)
    </xsl:for-each>Betriebskosten &#60; 500 USD oder &#62; 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

Pranav Patel
Pranav Patel

Reputation: 1559

in XSLT, you can try like Here I have added <xsl:text disable-output-escaping="yes">&#60;</xsl:text> and <xsl:text disable-output-escaping="yes">&#62;</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"/>&#160; <xsl:value-of select="@Name"/>&#160; (OC:<xsl:value-of select="@OperatingCostsDay"/>&#160;<xsl:value-of select="@currency"/>)
    </xsl:for-each> Betriebskosten  <xsl:text disable-output-escaping="yes">&#60;</xsl:text> 500 USD oder <xsl:text disable-output-escaping="yes">&#62;</xsl:text> 1 Mio. USD
  </xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions