XSLT 未声明的实体。现在给出编译错误,但它曾经工作

Posted

技术标签:

【中文标题】XSLT 未声明的实体。现在给出编译错误,但它曾经工作【英文标题】:XSLT Undeclared entity. Now giving Compile Error, but it used to work 【发布时间】:2019-08-18 04:58:25 【问题描述】:

简短摘要

当实际使用 !ENTITY 声明时,我们的 XSLT 样式表无法编译。说“对未声明实体的引用”。

我可以保留声明,并注释掉对该声明的实际调用,一切正常。

奇怪的是,同样的过程在过去 10 年中运行良好......并且在 2 个月前被使用,没有任何已知的修改。

尝试调试十年未修改的遗留代码,而我对 XSLT 的理解为零....


所有有趣的细节

transform.Load 函数调用 (XslCompiledTransform.Load)下图 1 失败。

Dim transfom As New XslCompiledTransform()

Dim readerSettings As New XmlReaderSettings()

readerSettings.DtdProcessing = DtdProcessing.Ignore

Using reader As XmlReader = XmlReader.Create(styleSheetFilePath, readerSettings)
    transfom.Load(reader, XsltSettings.TrustedXslt, resolver)
End Using

它给出的错误信息是

XSLT compile error.

Reference to undeclared entity 'cr'. Line 10, position 4.

StackTrace Information
*********************************************
   at System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader, Boolean include)
   at System.Xml.Xsl.Xslt.XsltLoader.Load(XmlReader reader)
   at System.Xml.Xsl.Xslt.XsltLoader.Load(Compiler compiler, Object stylesheet, XmlResolver xmlResolver)
   at System.Xml.Xsl.Xslt.Compiler.Compile(Object stylesheet, XmlResolver xmlResolver, QilExpression& qil)
   at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
   at System.Xml.Xsl.XslCompiledTransform.Load(XmlReader stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)

当我查看正在加载的 XSLT 文件时,第 10 行...它是 &cr; 实体引用。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE stylesheet [
<!ENTITY cr "<xsl:text> </xsl:text>">
]>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        &cr;
        <xsl:for-each select="node()">
            <xsl:call-template name="RemoveEmpty" />
        </xsl:for-each>
    </xsl:template>
..[redacted]..

【问题讨论】:

把DtdProcessing属性改成readerSettings.DtdProcessing = DtdProcessing.Parse是否有效? 来自spec:“XML 1.0 DTD 不支持 XML 命名空间,因此无法正确描述 XSLT 样式表的允许结构。” @Alejandro 规范最近有变化吗?我不知道为什么它会工作十年,直到最近......? @TimC 那行得通!!!!我不知道发生了什么变化(可能是 System.XML 的 .NET 框架 DLL 中的某些内容?)....但谢谢! @adam 这句话解释了为什么当您使用同时处理您的 DTD 的验证解析器时样式表会失败:如果您使用带有命名空间前缀的 QName 作为根元素,您将需要与DOCTYPE 声明中的相同前缀因为 XML 1.0 DTD 不支持 XML 命名空间。如果您选择使用非验证解析器,您可能无法解析您的实体... 【参考方案1】:

!ENTITY 之后应该有实体名称(在您的情况下为cr) 然后是字符代码。

据我了解,应该有回车字符的代码, 即 13(十进制)。

所以有问题的片段应该是:

<!DOCTYPE xsl:stylesheet [
<!ENTITY cr "&#13;">
]>

在我看来,"&lt;xsl:text&gt; &lt;/xsl:text&gt;" 很不寻常, 因为在 XSLT 代码的其他地方,它表示 空格

【讨论】:

以上是关于XSLT 未声明的实体。现在给出编译错误,但它曾经工作的主要内容,如果未能解决你的问题,请参考以下文章

XSLT 2.0 产生错误:“上下文项未定义”

为啥模块的导入导出会给出错误,因为声明了“BlogpostModule”但它的值从不读取.ts(6133)“角度7

如何在 XSLT 中插入

Swift 3 核心数据“实体”错误:`使用未声明的类型`

在保存实体 PrimaryGeneratedColumn 值未生成时,给出 NOT NULL 约束错误

尝试在 ANDROID 资源中使用 <!ENTITY 时出现错误:“实体已被引用,但未声明。”