0

背景: XML ドキュメントを rtf ドキュメントに変換する XSLT を開発しています。XSLT には GetImageString という msxsl:script 関数があり、指定された画像ファイルの文字列表現を返すので、画像を rtf ドキュメントに埋め込むことができます。

問題: xslCompiledTransform を xmlWriterSettings および XmlWriter と共に使用すると、変換の出力 (xsl:output method="text") にスクリプト関数の名前 (GetImageString) が含まれ、デフォルト以外のすべての名前空間のリストが含まれます。 XSL ファイル。xmlWriterSettings および XmlWriter クラスなしで XslCompiledTransform を使用すると、ファイルの先頭に BOM (バイト オーダー マーク) が挿入され、(少なくとも) MS Word rtf リーダーが混乱することを除いて、出力は正しくなります。したがって、BOM を抑制するには、XmlWritterSettings (および XmlWriter) クラスを使用する必要がありますが、埋め込まれた C# コードが呼び出されたときに出力が正しくありません。

これが私の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: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\wmetafile8</xsl:text>
      <GetImageString>
        <xsl:text> </xsl:text>
        <xsl:value-of select="rend:GetImageString(@path)"/>
      </GetImageString>
      <xsl:text>}</xsl:text>
    </xsl:template>

変換を呼び出す c# プログラムは次のとおりです。

    public void TransformWithMS()
    {
        XsltSettings xsltConfig = new XsltSettings(false,true);

        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load("scratch.xsl",xsltConfig,null);
        //xslt.Transform("divxml_modified.xml", "scratch.rtf");
        XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
        xmlWriterSettings.Encoding = new UTF8Encoding(false);
        xmlWriterSettings.ConformanceLevel = ConformanceLevel.Auto;
        XmlWriter results = XmlWriter.Create("scratch.rtf", xmlWriterSettings);
        xslt.Transform("divxml_modified.xml", results);
    }

問題のある出力は次のようになります。

{\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" 49492A00BC480000803...

(GetImageStringと名前空間のリストの周りに<と>がありますが、それを質問にフォーマットする方法を理解するのに苦労しています)

関数名と追加の名前空間を出力せずに (および BOM なしで) msxsl:script 関数を呼び出す方法を知っている人はいますか?

4

1 に答える 1