在ASP.NET中执行XSLT转换的最简化方法是什么?

时间:2009-08-12 20:16:15

标签: c# asp.net xml xslt

换句话说,是否有更快,更简洁的方式编写以下代码:

//Create an object for performing XSTL transformations
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(HttpContext.Current.Server.MapPath("/xslt/" + xsltfile.Value), new XsltSettings(true, false), new XmlUrlResolver());

//Create a XmlReader object to read the XML we want to format
//XmlReader needs an input stream (StringReader)
StringReader sr = new StringReader(node.OuterXml);
XmlReader xr = XmlReader.Create(sr);

//Create a StringWriter object to capture the output from the XslCompiledTransform object
StringWriter sw = new StringWriter();

//Perform the transformation
xslt.Transform(xr, null, sw);

//Retrieve the transformed XML from the StringWriter object
string transformedXml = sw.ToString();

更新(感谢目前为止的所有答案!):

对不起我的含糊不清:“更快”,更“简洁”,我的意思是,我是否包括任何不必要的步骤?此外,我会喜欢更“可读”的解决方案如果有人有。我在我正在开发的Web应用程序的一小部分中使用此代码,并且我将其移动到应用程序的大部分,所以我想确保它在移动之前尽可能整洁

此外,我从静态类(在单独的数据访问类库中)获取XML,该类与数据库通信。我还会在将转换后的XML字符串发送到网页之前对其进行操作。在这种情况下,我不确定输入/响应流是否仍然可行。

还有一件事:提供的XML和XSLT可能会发生变化(应用程序的用户可以对这两者进行更改),所以我想我每次都会被迫编译。

5 个答案:

答案 0 :(得分:11)

这是我为ASP.NET做的代码,与你的代码非常相似:

  XDocument xDoc = XDocument.Load("output.xml");

        XDocument transformedDoc = new XDocument();
        using (XmlWriter writer = transformedDoc.CreateWriter())
        {
            XslCompiledTransform transform = new XslCompiledTransform();
            transform.Load(XmlReader.Create(new StreamReader("books.xslt")));
            transform.Transform(xDoc.CreateReader(), writer);
        }

        // now just output transformedDoc

答案 1 :(得分:7)

如果您有一个大型XSLT,则可以在构建项目时通过将XSLT编译为.NET程序集来节省在运行时编译它的开销(例如,作为构建后步骤)。执行此操作的编译器称为xsltc.exe,是Visual Studio 2008的一部分。

为了加载这样的预编译的XSLT ,您需要在服务器上安装.NET Framework 2.0 SP1或更高版本(该功能是在SP1中引入的)。

例如,查看Anton Lapounov的博客文章:

  

XSLTC — Compile XSLT to .NET Assembly

如果预编译XSLT不是一个选项,你应该在加载后考虑缓存 XslCompiledTransform,这样你就不必在每次执行时都编译它变换。

答案 2 :(得分:3)

没有时间做一个完整的例子,但有些注意事项:

  1. XML与System.String不同。从类库中获取它作为XDocument或XmlDocument;以XDocument或XmlDocument完成它。
  2. 您可以使用ASP.NET Cache来存储已编译的XSL,并在.XSLT文件更改时具有缓存依赖性。
  3. 不要将XML转换为字符串,然后再转换回XML。使用node.CreateNavigator().ReadSubTree()
  4. 同样,使用XPathNavigator.AppendChild获取将写入XML文档的XmlWriter

答案 3 :(得分:2)

由于您提到ASP.NET,问题是您是否可以直接将响应流用于转换输出,以及是否可以直接使用输入流(如果它是POST ...)

答案 4 :(得分:0)

我会像这样重写代码:

string path = HttpContext.Current.Server.MapPath("/xslt/" + xsltfile.Value);
XmlReader reader = CreateXmlReader(node.OuterXml);
string transformedXml = Transform(path, reader);

private XmlReader CreateXmlReader(string text)
{
    StringReader reader = new StringReader(text);
    return XmlReader.Create(reader);
}

private string Transform(string xsltPath, XmlReader source)
{
    XsltCompiledTransform transformer = new XsltCompiledTransform();
    transformer.Load(
        xsltPath, 
        new XsltSettings(true, false), 
        new XmlUrlResolver());

    StringWriter writer = new StringWriter();
    transformer.Transform(source, null, writer);
    return writer.ToString();
}

我之所以重写代码是因为每个代码块现在只有一个目的。这使得阅读和理解更容易。此外,代码需要较少的注释,因为可以从函数名称及其参数中推断出大量信息。