如何在 C# 中应用 XSLT 样式表

我想使用 C# 将XSLT样式表应用到XML文档,并将输出写入文件。

143732 次浏览

我在这里找到了一个可能的答案:http://web.archive.org/web/20130329123237/http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=63

摘自文章:

XPathDocument myXPathDoc = new XPathDocument(myXmlFile) ;
XslTransform myXslTrans = new XslTransform() ;
myXslTrans.Load(myStyleSheet);
XmlTextWriter myWriter = new XmlTextWriter("result.html",null) ;
myXslTrans.Transform(myXPathDoc,null,myWriter) ;

编辑:

但是我可靠的编译器说,XslTransform是过时的:改用XslCompiledTransform:

XPathDocument myXPathDoc = new XPathDocument(myXmlFile) ;
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load(myStyleSheet);
XmlTextWriter myWriter = new XmlTextWriter("result.html",null);
myXslTrans.Transform(myXPathDoc,null,myWriter);

下面是一个关于如何在MSDN上用c#进行XSL转换的教程:

http://support.microsoft.com/kb/307322/en-us/

下面是如何写文件:

http://support.microsoft.com/kb/816149/en-us

作为旁注:如果你也想进行验证,这里有另一个教程(针对DTD, XDR和XSD (=Schema)):

http://support.microsoft.com/kb/307379/en-us/

我添加这个只是为了提供更多的信息。

根据Daren的精彩回答,请注意,这段代码可以通过使用适当的XslCompiledTransform。变换过载大大缩短:

var myXslTrans = new XslCompiledTransform();
myXslTrans.Load("stylesheet.xsl");
myXslTrans.Transform("source.xml", "result.html");

(抱歉把这个作为答案,但注释中的code block支持相当有限。)

在VB。NET,你甚至不需要一个变量:

With New XslCompiledTransform()
.Load("stylesheet.xsl")
.Transform("source.xml", "result.html")
End With

这可能对你有帮助

public static string TransformDocument(string doc, string stylesheetPath)
{
Func<string,XmlDocument> GetXmlDocument = (xmlContent) =>
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xmlContent);
return xmlDocument;
};


try
{
var document = GetXmlDocument(doc);
var style = GetXmlDocument(File.ReadAllText(stylesheetPath));


System.Xml.Xsl.XslCompiledTransform transform = new System.Xml.Xsl.XslCompiledTransform();
transform.Load(style); // compiled stylesheet
System.IO.StringWriter writer = new System.IO.StringWriter();
XmlReader xmlReadB = new XmlTextReader(new StringReader(document.DocumentElement.OuterXml));
transform.Transform(xmlReadB, null, writer);
return writer.ToString();
}
catch (Exception ex)
{
throw ex;
}


}

我想分享这一小段代码,它从数据库读取并使用XSLT进行转换。在顶部,我还使用了xslt-extensions,这使得它与其他的略有不同。

注意:这只是一个草案代码,在用于生产之前可能需要清理。

var schema = XDocument.Load(XsltPath);
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (var command = new SqlCommand(Sql, connection))
{
var reader = command.ExecuteReader();
var dt = new DataTable(SourceNode);
dt.Load(reader);
                    

string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine;
using (var stringWriter = new StringWriter())
{
dt.WriteXml(stringWriter, true);
xml += stringWriter.GetStringBuilder().ToString();
}


XDocument transformedXml = new XDocument();
var xsltArgumentList = new XsltArgumentList();
xsltArgumentList.AddExtensionObject("urn:xslt-extensions", new XsltExtensions());


using (XmlWriter writer = transformedXml.CreateWriter())
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(schema.CreateReader());
xslt.Transform(XmlReader.Create(new StringReader(xml)), xsltArgumentList, writer);
}
var result = transformedXml.ToString();
}
}

XsltPath是你的xslt文件的路径。
ConnectionString常量指向你的数据库。
Sql是你的查询。
SourceNode是源xml中每条记录的节点

现在有趣的部分,请注意上面代码中urn:xslt-extensionsnew XsltExtensions()的使用。如果需要一些复杂的计算(在xslt中可能无法实现),可以使用这种方法。下面是一个格式化日期的简单方法。

public class XsltExtensions
{
public string FormatDate(string dateString, string format)
{
DateTime date;


if (DateTime.TryParse(dateString, out date))
return date.ToString(format);


return dateString;
}
}

在XSLT文件中,您可以如下所示使用它;

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="urn:xslt-extensions">
...
<myTag><xsl:value-of select="ext:FormatDate(record_date, 'yyyy-MM-dd')"/></myTag>
...
</xsl:stylesheet>