DOCTYPE 已弃用,Xinclude 不这样做

DOCTYPE is deprecated and Xinclude does not do it

我需要一种方法来包含不包含全局 opening/closing tag/element 的零散 XML。该片段正在增长,因为程序不时将数据(更多块)附加到其中,因此它既没有结束标记也没有开始标记。我已经将 !DOCTYPE 与 !ENTITY 一起使用,但这已被弃用,新的​​ Xinclude 似乎无法导入它,因为它强制片段具有 "one" 开始和结束标记。

更多信息:以下内容适用于 IE-10,但不适用于 IE-11。后者不导入文件 current.log.

注意:根据此网站,Microsoft Edge 不支持它:https://docs.microsoft.com/en-us/internet-explorer/ie11-deploy-guide/deprecated-document-modes

<?xml version='1.0' encoding='ISO-8859-1'?>
<?xml-stylesheet type='text/xsl' href='IndexLog.xsl'?>

<!DOCTYPE myRoot [<!ENTITY thisMonthLog SYSTEM "current.log">]>

<myRoot>
    &thisMonthLog;
</myRoot>

日志 current.log 看起来像这样:

<block>
   <a>any text</a>
   <b>any text</b>
   <c>any text</c>
   <d>any text</d>
   <e>any text</e>
</block>
<block>
   <a>any text</a>
   <b>any text</b>
   <c>any text</c>
   <d>any text</d>
   <e>any text</e>
</block>

根据您的意见,我了解到您直接使用 IE 11 从文件系统加载 XML 文档。我认为 IE 已转而使用 MSXML 6 而不是 MSXML 3 默认用于 XSLT 和 MSXML 6 默认禁止 DTD 并且不加载外部实体。我知道绕过它的唯一方法是将 MSXML 6 与脚本一起使用并设置它必须允许 DTD 的属性,加载外部资源(对于您的情况,因为 DTD 仅用于加载外部资源实体,禁用验证):

<?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="yes" version="5" doctype-system="about:legacy-doctype"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Test</title>
                <script>
                    function runXslt(xmlUri, xsltUri, targetElement) {
                      var xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
                      xmlDoc.async = false;
                      xmlDoc.resolveExternals = true;
                      xmlDoc.validateOnParse = false;
                      xmlDoc.setProperty('ProhibitDTD', false);
                      xmlDoc.load(xmlUri);

                      var xsltDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
                      xsltDoc.async = false;
                      xsltDoc.load(xsltUri);

                      targetElement.insertAdjacentHTML('beforeEnd', xmlDoc.documentElement.transformNode(xsltDoc));
                    }
                </script>
                <script>
                    document.addEventListener(
                      'DOMContentLoaded',
                      function() {
                        runXslt('test201706070101.xml', 'test2017060701.xsl', document.body);
                      },
                      false
                    );
                </script>
            </head>
            <body>
                <h1>Test</h1>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="myRoot">
        <section>
            <h2>Content</h2>
            <xsl:apply-templates/>
        </section>  
    </xsl:template>

    <xsl:template match="block">
        <ul>
            <xsl:apply-templates/>
        </ul>
    </xsl:template>

    <xsl:template match="block/*">
        <li>
            <xsl:apply-templates/>
        </li>
    </xsl:template>

</xsl:stylesheet>

这样的话,如果输入文档test201706070101.xml的内容是

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test2017060701.xsl"?>
<!DOCTYPE myRoot [
  <!ENTITY thisMonthLog SYSTEM "test201706070102.xml">
]>
<myRoot>
    &thisMonthLog;
</myRoot>

在 IE 11 中加载并启用脚本,解析完整日志,例如第二个文件有

<?xml version="1.0" encoding="UTF-8"?>
<block>
    <a>any text</a>
    <b>any text</b>
    <c>any text</c>
    <d>any text</d>
    <e>any text</e>
</block>
<block>
    <a>any text</a>
    <b>any text</b>
    <c>any text</c>
    <d>any text</d>
    <e>any text</e>
</block>

并且样式表已经post编辑,IE window 中的输出是

Test


Content
•any text
•any text
•any text
•any text
•any text
•any text
•any text
•any text
•any text
•any text

所以外部实体已经加载。主要缺点显然是需要脚本,另一个缺点是使用的带有 MSXML 和 ActiveXObject 的脚本与 Edge 不兼容,因为它不支持 ActiveXObject.

我 post 这个答案是关于如果您想依靠 IE 进行 XSLT 转换可能有帮助的建议,从长远来看,将 XSLT 移动到 HTML 转换可能会更好到 .NET 这样的平台,您可以在其中更好地控制 XML 解析和 XSLT 处理的交互方式。

示例文件在 https://martin-honnen.github.io/xslt/2017/test201706070101.xml, https://martin-honnen.github.io/xslt/2017/test201706070102.xml and https://martin-honnen.github.io/xslt/2017/test2017060701.xsl 上在线,但我知道您想在本地而不是通过 HTTP(S) 执行此操作。