问题
Hey I try to validate my html page with official dtd :
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()){}
and custom 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 reading xml occurs validation and I get exception:
Parameter entity 'xhtml-inlstyle.mod' references itself. Line 111, position 21.
Error occurs here :
<!-- 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;]]>
I cannot understand why official dtd is wrong :/ What should I do ?
回答1:
Ugh! DTDs can get quite complex every now and then.
Let's disassemble your DTD snippet. For clarity I've re-wrapped the lines and added line numbers.
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;]]>
In this form we could say that lines 1 have 3 are entity declarations, lines 2 and 4 have text containing an entity reference.
First line is a plain old literal value entity and I'll add the replacement text in place of the reference on line 2. To add clarity, I'll omit the first line, add some whitespace as indentation and a line feed. Then we have:
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. ]]>
Line 2 becomes a markup section declaration with INCLUDE
keyword. The contents of the section in line 3 is an entity declaration for which the entity text is not a literal but an external entity declaration because of the keyword PUBLIC
. This means that the replacement text is not the following quoted text, but the contents of the referenced document, which location is specified by that formal public identifier and system identifier (the URL). If you are lucky and following the URL at the end of the line won't give you a time out error, you'll see that the contents of this external DTD is practically two parameter entity declarations. They are: <!ENTITY % style.attrib "style CDATA #IMPLIED">
and <!ENTITY % Core.extra.attrib "%style.attrib;" >
. By expanding the entity reference on line 4 your original piece of DTD technically results in this DTD snippet:
<![INCLUDE[
<!ENTITY % style.attrib "style CDATA #IMPLIED">
<!ENTITY % Core.extra.attrib "%style.attrib;" >
]]>
That doesn't look too erroneous to me, but peer review is appreciated of course. Therefore the next question is: why an error is raised, what could cause it?
Some possibilities that came to my mind:
Is the syntax you process correct and same as the one shown here? If the >
character is missing from the end of the second entity declaration, it is not terminated before the same entity is referenced (on line 4). Does parsing the declaration work only if it is written on a single line? Try re-wrapping it. Does the parser understand any other entity declarations than the ones with literal value? Try creating a similar entity declaration with public identifier but don't refer to it first. Could the problem be caused by the way how your (public/system) identifiers are resolved? Do you have a DTD catalogue, are you redirecting the possible DTD lookups over the net to your local copies, what happens if you change the URL to a local file (or a place that is not likely time out) etc. Is the INCLUDE
declaration around the entity declaration causing it to fail? Try moving it above the INCLUDE
declaration so it is also way ahead of the entity reference. Does the INCLUDE
work at all, try would using my last DTD snippet also cause an error.
By the way. XHTML 1.1 DTD contains many other include structures similar to this one, so this is probably not the only place which will raise an error. It was just the first one.
I'm gonna end this post to bad news. If this problem is not about some human error like misplaced or missing characters in your real DTD file, or if this is not about the way how the external DTD resources are retrieved, then I would guess that this problem is caused by bug/unsupported feature on your parser (which probably won't get fixed soon) or then (despite the error clearly pointing to the DTD file) this is caused by something in your C# code and compared to other folks here I have no clue about it and can't help you any further. Happy debugging anyway!
回答2:
You could validate against xhtml11-flat.dtd, which is an aggregation of xhtml11.dtd and all the *.mod files referenced by xhtml11.dtd.
Doing it this way, you should adjust your custom 'MyUrlResolver' class a little bit to return the 'xhtml11-flat.dtd' instead of 'xhtml11.dtd'.
回答3:
Solution for me was download xhtml11.dtd and all *.mod files referenced to dtd. Then I in dtd remove http links to
<!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;]]>
Now dtd during validation html page can use local dtd without download it from www ;)
来源:https://stackoverflow.com/questions/8502923/xhtml-1-1-validation-error-parameter-entity-xhtml-inlstyle-mod-references-it