XHTML 1.1验证错误:“参数实体'xhtml-inlstyle.mod'引用自身”

时间:2011-12-14 10:27:23

标签: c# xml xhtml dtd

嘿,我尝试用官方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);
    }
}

Durning读取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错了:/我该怎么办?

3 个答案:

答案 0 :(得分:2)

唉! DTD可能会不时变得非常复杂。

让我们反汇编你的DTD片段。为清楚起见,我重新包装了行并添加了行号。

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的内容实际上是两个参数实体声明。它们是:<!ENTITY % style.attrib "style CDATA #IMPLIED"><!ENTITY % Core.extra.attrib "%style.attrib;" >。通过扩展第4行的实体引用,您的原始DTD技术上会产生此DTD片段:

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

这对我来说看起来并不太错误,但同行评审当然是值得赞赏的。因此,下一个问题是:为什么会出现错误,导致错误的原因是什么?

我想到了一些可能性:

您处理的语法是否正确且与此处显示的语法相同?如果第二个实体声明的末尾缺少>字符,则在引用相同实体之前不会终止它(在第4行)。解析声明只有在单行写入时才有效吗?尝试重新包装它。解析器是否理解除具有字面值的实体声明之外的任何其他实体声明?尝试使用公共标识符创建类似的实体声明,但不要先引用它。问题可能是由您的(公共/系统)标识符的解析方式引起的吗?您是否有DTD目录,是否通过网络将可能的DTD查找重定向到本地副本,如果将URL更改为本地文件(或者不太可能超时的地方)会发生什么情况等等。{{{ 1}}实体声明周围的声明导致它失败?尝试将其移到INCLUDE声明之上,以便它也远远超过实体引用。 INCLUDE是否正常工作,尝试使用我的上一个DTD代码段也会导致错误。

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

我要以坏消息结束这篇文章。如果这个问题不是关于某些人为错误,例如您的真实DTD文件中放错位置或丢失字符,或者这与检索外部DTD资源的方式无关,那么我猜这个问题是由错误/不支持的功能引起的在您的解析器上(可能不会很快修复)或者然后(尽管错误明确指向DTD文件)这是由您的C#代码中的某些内容引起的,并且与其他人相比,我对此没有任何线索并且可以'帮你进一步。无论如何快乐的调试!

答案 1 :(得分:2)

您可以对xhtml11-flat.dtd进行验证,xhtml11.dtdenter image description here的聚合以及 xhtml11.dtd 引用的所有 * .mod 文件。

这样做,你应该调整你的自定义&#39; MyUrlResolver&#39;上课一点点回归&#39; xhtml11-flat.dtd&#39;而不是&#39; xhtml11.dtd&#39;。

答案 2 :(得分:0)

我的解决方案是下载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;]]>

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