【问题标题】:Prevent XSLT from removing end tags from empty nodes防止 XSLT 从空节点中删除结束标记
【发布时间】:2022-01-11 05:28:18
【问题描述】:

我有这个 XSLT 样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="no" />

    <xsl:template match="/">
        <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html></xsl:text>
        <xsl:call-template name="test" />
    </xsl:template>

    <xsl:template name="test">
        <html>

            <head>
                <link rel="stylesheet" href="style.css" />
                <script type="text/javascript" src="jquery.min.js"></script>
            </head>

            <body>
                <p>test</p>
            </body>

        </html>
    </xsl:template>

</xsl:stylesheet>

在 Visual Studio 2019 中,我尝试使用 C# 编写代码并使用 XslCompiledTransform 将此样式表转换为 HTML 代码。

// XSLT settings (that turns on the usage of 'document()' directive)
XsltSettings settings = new XsltSettings(true, true);
// Instantiate the transformer (enabled debug)
XslCompiledTransform xslt = new XslCompiledTransform(true);
// Load the data from XML
XPathDocument xml_config = new XPathDocument("input.xml");
// Load XSLT stylesheet
xslt.Load("stylesheet.xslt", settings, null);
// Prepare to write output
XmlTextWriter myWriter = new XmlTextWriter("output.html", Encoding.UTF8);
// Transform XML to HTML via XSLT
xslt.Transform(xml_config, null, myWriter);

结果输出:(损坏的 html)

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="style.css" />
    <script type="text/javascript" src="jquery.min.js" />
</head>

<body>
    <p>test</p>
</body>

</html>

Xslt 转换器由于某种原因使标签自闭,从而破坏了 HTML 代码。这使得 body 和 p 标签成为脚本的子标签 - 因此不会渲染它。

一种解决方案是将&amp;#160; 添加到脚本标签,这样它就不再被认为是空的,也不会自动关闭 &lt;script type="text/javascript" src="jquery.min.js"&gt;&amp;#160;&lt;/script&gt; 然而,这不是一个解决方案,因为并不总是可以编辑传入的 XML 文件。有没有其他解决方案?我在我的cs源代码中错过了什么吗?还是我必须使用非默认 XSLT 转换器?

有人建议将其放在样式表中: &lt;xsl:output method="html" /&gt; 但这只是由于某种原因不起作用

【问题讨论】:

    标签: c# html xslt


    【解决方案1】:

    您不应将XmlTextWriter 用作目标,而应仅使用xslt.Transform("input.xml", "output.html"),这样XSLT 处理器将负责序列化并可以应用您的xsl:output 设置。

    如果您确实需要 XmlWriter 作为目的地,请确保您使用例如创建一个 XmlWriter XmlWriter.Create("output.html", xslt.OutputSettings).

    【讨论】:

    • 太棒了。简短而清晰。但最重要的是——我还没有在网上看到这个信息。谢谢!