2011-12-14 75 views
0

嘿,我嘗試驗證我的HTML頁面官方DTD:XHTML 1.1驗證錯誤: 「參數實體 'XHTML-inlstyle.mod' 引用自身」

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驗證時,我得到異常:這裏發生

Parameter entity 'xhtml-inlstyle.mod' references itself. Line 111, position 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是錯的:/我該怎麼辦?

+0

@DevNull代碼暗示它是XHTML 1.1,它是模塊化的。 – jasso 2011-12-16 21:22:51

回答

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;]]> 

中驗證HTML頁面現在DTD可以使用本地DTD沒有從WWW下載它;)

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. <![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更改爲本地文件(或不可能超時的地方)等等,會發生什麼情況等等。INCLUDE聲明圍繞實體聲明導致它失敗?嘗試將它移動到INCLUDE聲明之上,這樣它也比實體引用領先。 INCLUDE是否可以運行,嘗試使用我最後一個DTD片段也會導致錯誤。

順便說一句。 XHTML 1.1 DTD包含許多與此類似的其他包含結構,所以這可能不是唯一會引發錯誤的地方。這只是第一個。

我要結束這篇文章壞消息。如果這個問題不是關於真實DTD文件中錯誤放置或缺少字符的人爲錯誤,或者這與外部DTD資源檢索方式無關,那麼我會猜測這個問題是由錯誤/不支持的功能引起的在你的解析器(可能不會很快修復)或者(儘管錯誤明確指向DTD文件),這是由你的C#代碼中的某些東西引起的,並且與其他人相比,我不知道它,不會再幫助你。無論如何,快樂調試!

+0

可能是一個.NET 4.0錯誤:http://thejoyofcode.com/Validator_Module.aspx – mzjn 2011-12-16 21:46:11

2

你可以驗證對xhtml11-flat.dtd,這是xhtml11.dtd和所有聚集 * .mod文件引用 xhtml11.dtd

這樣做,您應該調整您的自定義'MyUrlResolver'類以返回'xhtml11-flat.dtd'而不是'xhtml11.dtd'。