2012-10-04 43 views
1

我創建一個XSLT和XML文件中動態顯示我的問卷&救我的問題選項(下拉列表)。現在我想使用流而不是寫在實際的文件上。所以,這就是我正在做它:?XSLT編譯錯誤使用的MemoryStream

XmlReader xslt_reader; 
XmlReader xml_reader; 

PageLoad(){ 
    Fn_CreateXSL(); 
    Fn_CreateXML(); 
    LoadQuestionnaire(); 
} 

Fn_CreateXSL(){ 
    xslt_stream = new MemoryStream(); 

    XmlTextWriter objXSLTWriter = new XmlTextWriter(xslt_stream, Encoding.UTF8); 

    objXSLTWriter.Formatting = Formatting.Indented; 
    objXSLTWriter.WriteStartDocument(); 
    .......... 
    objXSLTWriter.WriteEndDocument(); 
    xslt_stream.Seek(0, SeekOrigin.Begin); 
    xslt_reader = XmlReader.Create(xslt_stream); 
} 

Fn_CreateXML(){ 
    xmlt_stream = new MemoryStream(); 

    XmlTextWriter objXMLTWriter = new XmlTextWriter(xmlt_stream, Encoding.UTF8); 

    objXMLTWriter.Formatting = Formatting.Indented; 
    objXMLTWriter.WriteStartDocument(); 
    .......... 
    objXMLTWriter.WriteEndDocument(); 
    xmlt_stream.Seek(0, SeekOrigin.Begin); 
    xmlt_reader = XmlReader.Create(xmlt_stream); 
} 

LoadQuestionnaire(){ 
    XslCompiledTransform var_xsl_trans = new XslCompiledTransform(); 

    // also tried var_xsl_trans.Load(xslt_reader, null, new XmlUrlResolver()); 
    var_xsl_trans.Load(xslt_reader); // XSLT Compile Error occurs 

    StringWriter sw = new StringWriter(); 

    var_xsl_trans.Transform(xml_reader, null, sw); 
} 

但我正在逐漸「XSLT編譯錯誤,當我試圖加載任何的想法

+0

你還沒有告訴我們當使用兩個FN_ *功能,也沒有什麼值分配給xslt_reader。如果您提供一個簡短的*完整的*程序來證明問題,這將非常有幫助。 –

+0

我在頁面加載時調用了這些函數(我修改了我的問題)。約xslt_reader我在Fn_CreateXSL分配值還是你的意思是某物別的嗎?] – SZT

+0

好,一個簡短而完整的控制檯應用程序將使這一個*很多*簡單的診斷。 –

回答

0

由於@kevin註釋中,下列固定我的問題,但我不明白爲什麼它的工作,但(有一些的想法,但不知道)

的xmlt_stream.Seek(0, SeekOrigin.Begin)之前加入objXMLTWriter.Flush();

1

下面是對我的作品的辦法

而不是使用XmlWriter-> MemoryStream->的XmlReader我會用XElement微軟與LINQ .NET 3.5中引入的。XslCompiledTransform類的兩個LoadTransform方法具有重載內搭IXPathNavigable作爲參數來傳遞XML。這個接口有隻有一種方法XPathNavigator CreateNavigator()一個d XElement有這樣的方法。我不知道爲什麼微軟沒有聲明XElement實現了這個接口。可能他們忘了:-)。所以,爲了彌補這個疏忽,我實施了6個線路轉換器類XNavigable。你會在下面看到它。這裏的Page_Load()的OP的模擬:

public void Generate() 
{ 
    XElement inputXml = CreateInputXml(); 
    XElement transformXslt = CreateTransformXslt(); 

    XslCompiledTransform transform = new XslCompiledTransform(); 
    transform.Load(new XNavigable(transformXslt), null, null); 

    MemoryStream outputStream = new MemoryStream(); 
    transform.Transform(new XNavigable(inputXml), null, outputStream); 

    byte[] outputBytes = outputStream.ToArray(); 
    string outputString = Encoding.UTF8.GetString(outputBytes); 
} 

我用MemoryStream代替StringWriter因爲StringWriter的總是創造我UTF-16編碼XML作爲輸出。我認爲UTF-16是由StringWriter強加的,因爲底層字符串每個字符有16位。使用MemoryStream,我們可以控制編碼。

爲了完整這裏是我的CreateInputXmlCreateTransformXslt方法的代碼。他們只是例子。當然,可以使用XElement.Add()方法來生成內容。我只是使用其中列出的所有節點的構造函數來快速硬編碼。在上面的代碼

private static XElement CreateTransformXslt() 
    { 
     //XSL to substitute <placeholder/> with <realElement/> and copy everything else. 
     //<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform"> 
     // <output indent="yes" /> 
     // <template match="@* | node()"> 
     // <copy> 
     //  <apply-templates select="@* | node()" /> 
     // </copy> 
     // </template> 
     // <template match="placeholder"> 
     // <realElement xmlns="" /> 
     // </template> 
     //</stylesheet> 
     XNamespace xsl = "http://www.w3.org/1999/XSL/Transform"; 
     XNamespace empty = ""; 
     XElement transformXslt = new XElement(xsl + "stylesheet", new XAttribute("version", "1.0"), 
      new XElement(xsl + "output", new XAttribute("indent", "yes")), 
      //new XElement(xsl + "strip-space", new XAttribute("elements", "*")), 
      new XElement(xsl + "template", new XAttribute("match", "@* | node()"), 
       new XElement(xsl + "copy", 
        new XElement(xsl + "apply-templates", new XAttribute("select", "@* | node()")) 
       ) 
      ), 
      new XElement(xsl + "template", new XAttribute("match", "placeholder"), 
       new XElement("realElement") 
      ) 
     ); 
     return transformXslt; 
    } 

    private static XElement CreateInputXml() 
    { 
     XElement origXml = new XElement(new XElement("Root", 
              new XElement("Child1", "data1"), 
              new XElement("placeholder"), 
              new XElement("Child2", "data2"))); 
     return origXml; 
    } 

有一個問題是,我們不應該在XSL使用xsl:strip-space elements="*"。它在上面評論。這是因爲XslCompiledTransform具有當輸入XML作爲IXPathNavigable通過剝離空間問題。在錯誤消息中,它建議使用XmlReader,如果我需要剝離。我不認爲剝離空間對於生成網頁非常重要。

最後,這裏是在開頭提到的轉換器類:

class XNavigable : IXPathNavigable 
{ 
    XElement _xElement; 
    public XNavigable(XElement xElement) 
    { 
     _xElement = xElement; 
    } 

    public XPathNavigator CreateNavigator() 
    { 
      return _xElement.CreateNavigator(); 
    } 
}