2013-10-23 81 views
0

背景: 我正在開發一個XSLT以將XML文檔轉換爲rtf文檔。 XSLT有一個名爲GetImageString的msxsl:腳本函數,它返回給定圖像文件的字符串表示形式,以便將圖像嵌入到rtf文檔中。xslcompiledtransform輸出函數和名稱空間的名稱

問題: 當xslCompiledTransform使用具有xmlWriterSettings和變換的的XmlWriter輸出(XSL:輸出方法=「文本」)包括腳本函數(GetImageString)的名稱與所有的非的列表沿包含在XSL文件中的默認名稱空間。如果我使用不帶xmlWriterSettings和XmlWriter類的XslCompiledTransform,則輸出是正確的,除了在文件頂部插入BOM(字節順序標記)(至少)混淆MS Word rtf閱讀器。因此,爲了抑制物料清單,我必須使用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 = 「甕:架構 - 微軟COM:XSLT」>的xmlns:雷德= 「甕:撕裂的腳本」 49492A00BC480000803 ...

(有一個<和一個>圍繞GetImageString和名稱列表,但我無法弄清楚如何將其格式化爲問題)

任何人都知道如何調用msxsl:腳本函數,而不輸出函數名稱和額外名稱空間沒有BOM)?

回答

0

如果你想改變.NET代碼輸出的設置,那麼你應該使用

XmlWriterSettings myOutputSettings = xslt.OutputSettings.Clone(); 
myOutputSettings.Encoding = new UTF8Encoding(false); 

現在,例如創建的XmlWriter

using (XmlWriter result = XmlWriter.Create("scratch.rtf", myOutputSettings)) 
{ 
    xslt.Transform("divxml_modified.xml", result); 
} 

這允許您有一個XmlWriter,它根據xsl:output輸出,但編碼已更改。

是否解決了出現在輸出中的代碼的問題我不確定,請嘗試並報告回來。

+0

謝謝你的回答!使用'Clone'來創建XmlWriterSettings的技巧。另一個論壇上的人建議標記是不必要的,通過刪除這些標記,我也能夠使其工作正常。 –