【问题标题】:XHTML 1.1 validation error: "Parameter entity 'xhtml-inlstyle.mod' references itself"XHTML 1.1 验证错误:“参数实体 'xhtml-inlstyle.mod' 引用自身”
【发布时间】:2016-04-26 04:08:58
【问题描述】:

嘿,我尝试使用官方 dtd 验证我的 html 页面:

MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(MessageBody));
ms.Position = 0;
XmlReaderSettings settingsReader = new XmlReaderSettings();
settingsReader.DtdProcessing = DtdProcessing.Parse;
settingsReader.ValidationType = ValidationType.DTD;
MyUrlResolver resolver = new MyUrlResolver();
settingsReader.XmlResolver = resolver;
 XmlReader reader = XmlReader.Create(ms, settingsReader);
 while(reader.Read()){}

和自定义 XmlUrlResolver:

class MyUrlResolver : System.Xml.XmlUrlResolver
{
    public MyUrlResolver()
    { }

    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    {
        if (File.Exists(System.Web.Hosting.HostingEnvironment.MapPath("~/dtd/xhtml11.dtd")))
        {
            absoluteUri = new Uri(System.Web.Hosting.HostingEnvironment.MapPath("~/dtd/xhtml11.dtd"));
        }
        return base.GetEntity(absoluteUri, role, ofObjectToReturn);
    }

    public override Uri ResolveUri(Uri baseUri, string relativeUri)
    {
        baseUri = new Uri(System.Web.Hosting.HostingEnvironment.MapPath("~"));
        relativeUri = "dtd/xhtml11.dtd";
        return base.ResolveUri(baseUri, relativeUri);
    }
}

在读取 xml 时发生验证,我得到异常:

参数实体 'xhtml-inlstyle.mod' 引用自身。第 111 行,第 21 位。

这里发生错误:

   <!-- Inline Style Module  ........................................ -->
<!ENTITY % xhtml-inlstyle.module "INCLUDE" >
<![%xhtml-inlstyle.module;[
<!ENTITY % xhtml-inlstyle.mod
     PUBLIC "-//W3C//ELEMENTS XHTML Inline Style 1.0//EN"
            "http://www.w3.org/MarkUp/DTD/xhtml-inlstyle-1.mod" >
%xhtml-inlstyle.mod;]]>

我不明白为什么官方 dtd 是错误的:/ 我该怎么办?

【问题讨论】:

  • @DevNull 代码暗示它是模块化的 XHTML 1.1。

标签: c# xml xhtml dtd


【解决方案1】:

啊! DTD 有时会变得相当复杂。

让我们反汇编您的 DTD sn-p。为了清楚起见,我重新换行并添加了行号。

1.    <!ENTITY % xhtml-inlstyle.module "INCLUDE" >
2.    <![%xhtml-inlstyle.module;[
3.    <!ENTITY % xhtml-inlstyle.mod PUBLIC "-//W3C//ELEMENTS XHTML Inline Style 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-inlstyle-1.mod" >
4.    %xhtml-inlstyle.mod;]]>

在这种形式中,我们可以说第 1 行有 3 行是实体声明,第 2 行和第 4 行有包含实体引用的文本。

第一行是一个普通的旧文字值实体,我将添加替换文本来代替第 2 行的引用。为了清楚起见,我将省略第一行,添加一些空格作为缩进和换行符.然后我们有:

2.    <![INCLUDE[
3.        <!ENTITY % xhtml-inlstyle.mod PUBLIC "-//W3C//ELEMENTS XHTML Inline Style 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-inlstyle-1.mod" >
4.        %xhtml-inlstyle.mod;
5.    ]]>

第 2 行成为带有 INCLUDE 关键字的标记部分声明。第 3 行部分的内容是一个实体声明,由于关键字 PUBLIC,其实体文本不是文字而是外部实体声明。这意味着替换文本不是下面的引用文本,而是引用文档的内容,其位置由正式的公共标识符和系统标识符(URL)指定。如果你很幸运并且跟随行尾的 URL 不会给你一个超时错误,你会看到这个外部 DTD 的内容实际上是两个参数实体声明。它们是:&lt;!ENTITY % style.attrib "style CDATA #IMPLIED"&gt; 和 &lt;!ENTITY % Core.extra.attrib "%style.attrib;" &gt;。通过扩展第 4 行的实体引用,您的原始 DTD 在技术上会产生此 DTD sn-p:

<![INCLUDE[
    <!ENTITY % style.attrib "style CDATA #IMPLIED">
    <!ENTITY % Core.extra.attrib "%style.attrib;" >
]]>

这在我看来并没有太大的错误,但同行评审当然值得赞赏。因此下一个问题是:为什么会引发错误,是什么原因导致的?

我想到的一些可能性:

您处理的语法是否正确且与此处显示的语法相同?如果在第二个实体声明的末尾缺少&gt; 字符,则它不会在引用同一实体之前终止(在第 4 行)。仅当声明写在一行上时解析声明才有效?尝试重新包装它。除了具有文字值的实体声明之外,解析器是否理解任何其他实体声明?尝试使用公共标识符创建类似的实体声明,但不要先引用它。问题可能是由您的(公共/系统)标识符的解析方式引起的吗?您是否有 DTD 目录,您是否将可能的 DTD 查找通过网络重定向到您的本地副本,如果您将 URL 更改为本地文件(或不太可能超时的地方)会发生什么等。@987654329实体声明周围的@声明导致它失败?尝试将其移至 INCLUDE 声明上方,使其也位于实体引用之前。 INCLUDE 是否有效,尝试使用我的最后一个 DTD sn-p 也会导致错误。

顺便说一句。 XHTML 1.1 DTD 包含许多与此类似的其他包含结构,因此这可能不是唯一会引发错误的地方。这只是第一个。

我要以坏消息结束这篇文章。如果此问题与真实 DTD 文件中的某些人为错误(例如错位或丢失字符)无关,或者与检索外部 DTD 资源的方式无关,那么我猜想此问题是由错误/不支持的功能引起的在您的解析器上(可能不会很快得到修复)或然后(尽管错误清楚地指向 DTD 文件)这是由您的 C# 代码中的某些内容引起的,与这里的其他人相比,我对此一无所知并且可以'不会再帮你了。祝调试愉快!

【讨论】:

    【解决方案2】:

    您可以针对xhtml11-flat.dtd 进行验证,它是xhtml11.dtd 和xhtml11.dtd 引用的所有*.mod 文件的聚合。

    这样做,您应该稍微调整您的自定义“MyUrlResolver”类以返回“xhtml11-flat.dtd”而不是“xhtml11.dtd”。

    【讨论】:

      【解决方案3】:

      我的解决方案是下载 xhtml11.dtd 和所有引用 dtd 的 *.mod 文件。然后我在 dtd 中删除 http 链接到

          <!ENTITY % xhtml-datatypes.module "INCLUDE" >
      <![%xhtml-datatypes.module;[
      <!ENTITY % xhtml-datatypes.mod
           PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN"
                  "xhtml-datatypes-1.mod" >
      %xhtml-datatypes.mod;]]>
      

      现在验证 html 页面期间的 dtd 可以使用本地 dtd 而无需从 www 下载;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        相关资源
        最近更新 更多