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

    Question

  • 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"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xpp="http://www.sdl.com/xpp"
        xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
        xmlns:v="urn:schemas-microsoft-com:vml"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:rend="urn:rend-scripts">
        <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"/>
          <xsl:text>
    };</xsl:text>
        </xsl:template>
    
      <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"/>
        <![CDATA[
            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;
            }
            ]]>
      </msxsl:script>
      
        <xsl:template match="xpp:image">
          <xsl:text>
    {\pict</xsl:text>
          <xsl:choose>
            <xsl:when test="@type = 'jpg'">
              <xsl:text>\jpegblip</xsl:text>
            </xsl:when>
            <xsl:when test="@type = 'tif'">
              <xsl:text>\wmetafile8</xsl:text>
            </xsl:when>
            <xsl:when test="@type = 'gif'">
              <xsl:text>\pngblip</xsl:text>
            </xsl:when>
            <xsl:when test="@type = 'png'">
              <xsl:text>\pngblip</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>No rtf image implementation for file type: </xsl:text><xsl:value-of select="@type"/>        
            </xsl:otherwise>
          </xsl:choose>
          <GetImageString>
            <xsl:text> </xsl:text>
            <xsl:value-of select="rend:GetImageString(@path)"/>
          </GetImageString>
          <xsl:text>}</xsl:text>
        </xsl:template>
    
      <xsl:template match="xpp:style">
        <xsl:value-of select="@name"/>
        <xsl:apply-templates/>
      </xsl:template>
    
        <xsl:template match="xpp:style" name="GetStyles">
          <xsl:text>
          </xsl:text>
          <xsl:variable name="font" select="@font"></xsl:variable>
          <xsl:text>{\f</xsl:text><xsl:value-of select="position()"/>
          <xsl:choose>
            <xsl:when test="$font='Times-Roman'">
              <xsl:text> Times New Roman;}</xsl:text></xsl:when>
          <xsl:otherwise>
          <xsl:text> </xsl:text><xsl:value-of select="$font"/><xsl:text>;}</xsl:text>
          </xsl:otherwise>
          </xsl:choose>
        </xsl:template>
        
        
    </xsl:stylesheet>


    Here is the C# program to do the transformation:

    public void TransformWithMS()
    {
        XsltSettings xsltConfig = new XsltSettings(false,true);
                
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load("scratch.xsl",xsltConfig,null);
        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="http://www.sdl.com/xpp" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 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

Answers

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