XslCompiledTransform with XmlWriterSettings/XmlWriter outputs msxsl:script function name and namespaces


  • I am developing an XSLT to transform an xml document to an rtf document.  Within the XSLT is an msxsl:script function called GetImageString and is intended to produce a string that represents the given image file.  Using the XslCompiledTransform class I was able to output a text file as I wanted except that the BOM (byte order mark) was being placed at the top of the file.  I didn't want that so I found that I could use an XmlWriterSettings class to specify not to include the BOM.  This worked well, except now the output includes the name of the embedded script and a list of namespaces.  I do not want that and do not know why it is showing up.  Can anyone help me get around this problem?

    Here is the XSL:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        <xsl:output method="text" encoding="utf-8"/>
        <!--<xsl:variable name="fonts" select="document/styles/style[font='Times-Roman']"></xsl:variable> -->
        <xsl:template match="xpp:document">          
          <xsl:text>{\rtf1\ansi {\fonttbl </xsl:text>
          <xsl:apply-templates select="//xpp:style"/>
          <xsl:text> }</xsl:text>
          <xsl:apply-templates select ="//xpp:image"/>
      <msxsl:script language="c#" implements-prefix="rend">
        <msxsl:assembly href="C:\Projects\LearningRTF\System.IO.dll"/>
        <msxsl:assembly href="C:\Projects\LearningRTF\System.Drawing.dll"/>
        <msxsl:using namespace="System.IO"/>
        <msxsl:using namespace="System.Drawing"/>
            public string GetImageString(string path_to_image){
              MemoryStream stream = new MemoryStream();
              Image img = Image.FromFile(path_to_image);
              img.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
              byte[] bytes = stream.ToArray();
              string output = BitConverter.ToString(bytes, 0).Replace("-", string.Empty);
              return output;
        <xsl:template match="xpp:image">
            <xsl:when test="@type = 'jpg'">
            <xsl:when test="@type = 'tif'">
            <xsl:when test="@type = 'gif'">
            <xsl:when test="@type = 'png'">
              <xsl:text>No rtf image implementation for file type: </xsl:text><xsl:value-of select="@type"/>        
            <xsl:text> </xsl:text>
            <xsl:value-of select="rend:GetImageString(@path)"/>
      <xsl:template match="xpp:style">
        <xsl:value-of select="@name"/>
        <xsl:template match="xpp:style" name="GetStyles">
          <xsl:variable name="font" select="@font"></xsl:variable>
          <xsl:text>{\f</xsl:text><xsl:value-of select="position()"/>
            <xsl:when test="$font='Times-Roman'">
              <xsl:text> Times New Roman;}</xsl:text></xsl:when>
          <xsl:text> </xsl:text><xsl:value-of select="$font"/><xsl:text>;}</xsl:text>

    Here is the C# program to do the transformation:

    public void TransformWithMS()
        XsltSettings xsltConfig = new XsltSettings(false,true);
        XslCompiledTransform xslt = new XslCompiledTransform();
        XmlWriterSettings xmlWriterSettings = new    XmlWriterSettings();
        xmlWriterSettings.Encoding = new UTF8Encoding(false);
        xmlWriterSettings.ConformanceLevel = ConformanceLevel.Auto;
        XmlWriter results = XmlWriter.Create("scratch.rtf", xmlWriterSettings);
        xslt.Transform("my.xml", results);

    This is a snippet showing the offending output:

    {\rtf1\ansi {\fonttbl 
          {\f1 Times New Roman;} }
    {\pict\wmetafile8<GetImageString xmlns:xpp="" xmlns:w="" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:rend="urn:rend-scripts"> 49492A00BC480000803FE04...

    Wednesday, October 23, 2013 5:32 PM


All replies

  • If you want to output as text rather than XML, then why do you have the <GetImageString> and </GetImageString> tags in the stylesheet at all?

    On second thought, you'll also have to set

    xmlWriterSettings.OutputMethod = XmlOutputMethod.Text;

    in order to prevent XmlWriter from replacing "&" with "&amp;" and so on.

    Wednesday, October 23, 2013 8:01 PM
  • Thank you so much!!  I'm pretty new to using XSLT and was following another example that used those type of tags around the call to the embedded function.  Removing the <GetImageString> and </GetImageString> tags worked!
    Thursday, October 24, 2013 1:28 AM