我想要轉換的HTML標記轉化HTML與.NET中的撒克遜庫(XSL 2.0)
我使用撒克遜庫,因爲.NET 4.5本身不支持XSL 2.0文本文本。 http://saxon.sourceforge.net/#F9.7HE
當我在http://xslttest.appspot.com/上運行我的xsl腳本時,我沒有收到任何錯誤,輸出正確。
HTML代碼:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>Test Title</title>
</head>
<body>
<h1>Test Header</h1>
<p>Blah Blah Blah</p>
<p class="center"><img src="ignore.jpeg" alt="ignore"/></p>
<div class="Test"><p>More Text</p></div>
</body>
</html>
XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:output method="text" media-type="text"/>
<xsl:template match="/xhtml:html">
<xsl:call-template name="print-it">
<xsl:with-param name="nodeToPrint" select="xhtml:body"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="print-it">
<xsl:param name="nodeToPrint"/>
<xsl:for-each select="child::*">
<xsl:choose>
<xsl:when test="matches(lower-case(local-name(.)), 'h[123456]|p|div|title')">
<xsl:value-of select="concat(normalize-space(replace(string-join(text(), ''), '''', '')), ' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(replace(string-join(text(), ''), '''', ''))"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="print-it">
<xsl:with-param name="nodeToPrint" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
輸出:
Test Title
Test Header
Blah Blah Blah
More Text
但是,當我嘗試做在.NET中的轉換,我得到一個異常。我不確定這個問題是否與XSL腳本有關,並且在線轉換器是否原諒或者撒克遜圖書館是否放棄了該球。
異常消息:
Exception thrown: 'System.InvalidOperationException' in saxon9he.dll
Additional information: The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type.
.NET代碼:
using Saxon.Api;
var xslt = new FileInfo(@"C:\path\to\stylesheet.xslt");
var input = new FileInfo(@"C:\path\to\data.xml");
var output = new FileInfo(@"C:\path\to\result.xml");
// Compile stylesheet
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
// Do transformation to a destination
var destination = new DomDestination();
using(var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
// Save result to a file (or whatever else you wanna do)
destination.XmlDocument.Save(output.FullName);
UPDATE:
謝謝MartinHonnen。你的建議奏效了。
Serializer _serializer = new Serializer();
MemoryStream _ms = new MemoryStream();
String _outputStream = new StreamWriter(_ms, new UTF8Encoding(false));
_serializer.SetOutputWriter(_outputStream);
using (inputStream == input.OpenRead()) {
XsltTransformer transformer = executable.Load();
transformer.MessageListener = new SaxtonMessageListener();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(_serializer);
}
String _text = Encoding.UTF8.GetString(_ms.ToArray());
在什麼行是拋出的異常? –
嗯,問題是你的樣式表沒有創建一個格式良好的XML文檔,它適合DOM目的地,而是隻包含文本的片段。我不確定你想做什麼,需要XSLT 2.0和Saxon,因爲沒有使用樣式表中的模板,因爲輸入中沒有名稱空間中的元素,而且樣式表與XHTML名稱空間相匹配,但該結果僅適用於http://saxonica.com/html/documentation/dotnetdoc/Saxon/Api/DomDestination.html#DomDestination(System.Xml.XmlDocumentFragment)。不管你是否需要DOM,都不清楚。 –
@Örvar在transformer.Run(目的地); – user3541092