2012-10-04 27 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(); 
    } 
}