Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET(XSL 2.0)中的Saxon库将HTML转换为文本_C#_Html_Xml_Xslt_Saxon - Fatal编程技术网

C# 使用.NET(XSL 2.0)中的Saxon库将HTML转换为文本

C# 使用.NET(XSL 2.0)中的Saxon库将HTML转换为文本,c#,html,xml,xslt,saxon,C#,Html,Xml,Xslt,Saxon,我正在尝试将HTML标记转换为文本 我之所以使用Saxon库,是因为.NET4.5本机不支持XSL2.0。 当我在上运行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.idp

我正在尝试将HTML标记转换为文本

我之所以使用Saxon库,是因为.NET4.5本机不支持XSL2.0。

当我在上运行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>
<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
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);
然而,当我尝试在.NET中进行转换时,我遇到了一个异常。我不确定问题是否出在XSL脚本上,在线转换器是否可以原谅,或者Saxon库是否有问题

异常消息:

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代码

<?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>
<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
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);
更新

谢谢你,马丁霍宁。你的建议奏效了

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());

如果您只需要一个字符串或文本文件,那么您可以使用并设置您是否需要一个文件,或者创建一个
StringWriter
并将其传递给,然后在
运行
调用后,您只需在创建的StringWriter上使用
ToString()

引发异常的行是什么?好的,问题在于,样式表并没有创建一个格式良好的XML文档(可以放入DOM目标),而是创建一个只包含文本的片段。我不确定需要XSLT 2.0和Saxon做什么,因为没有使用样式表中的任何模板,因为输入没有名称空间中的元素,并且您的样式表与XHTML名称空间匹配,但结果仅适用于。您是否需要DOM尚不清楚。@transformer.Run(destination)上的Örvar;line@MartinHonnen非常感谢。我完全忽略了这一点。我只需要文本。不是一个格式良好的DOM。我还更新了HTML示例。@MartinHonnen-谢谢你的链接。这是为我分配的东西。然而,我没有看到一个“目的地”对象适合我的需要。你有什么建议吗?