换句话说,是否有更快,更简洁的方式编写以下代码:
//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可能会发生变化(应用程序的用户可以对这两者进行更改),所以我想我每次都会被迫编译。
答案 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的博客文章:
如果预编译XSLT不是一个选项,你应该在加载后考虑缓存 XslCompiledTransform
,这样你就不必在每次执行时都编译它变换。
答案 2 :(得分:3)
没有时间做一个完整的例子,但有些注意事项:
Cache
来存储已编译的XSL,并在.XSLT文件更改时具有缓存依赖性。node.CreateNavigator().ReadSubTree()
。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();
}
我之所以重写代码是因为每个代码块现在只有一个目的。这使得阅读和理解更容易。此外,代码需要较少的注释,因为可以从函数名称及其参数中推断出大量信息。