我和 Dave 遇到了相同的问题,然后找到了这个问题并得到了很大帮助。基于 Dave 的答案和 Pavel 的优化建议,我更新了这个类。现在 DTDs 可以作为内嵌资源存储,并在必要时加载。我知道这篇文章已经几年了,但也许对某个人会有所帮助。
用法示例:
XmlReaderSettings readerSettings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Parse,
XmlResolver = new LocalXhtmlXmlResolver()
};
using (XmlReader reader = XmlReader.Create(xhtmlStream, readerSettings))
{
XDocument xhtml = XDocument.Load(reader);
...
}
LocalXhtmlXmlResolver类:
该类用于解析本地的XHTML和XML文件。
public class LocalXhtmlXmlResolver : XmlUrlResolver
{
private const string ResourcePrefix = "Your.Namespace.Here.";
private static readonly Dictionary<string, string> _knownDtds = new Dictionary<string, string>
{
{ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", ResourcePrefix + "xhtml1-strict.dtd" },
{ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", ResourcePrefix + "xhtml1-transitional.dtd" },
{ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd", ResourcePrefix + "xhtml1-frameset.dtd" },
{ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd", ResourcePrefix + "xhtml11.dtd" },
{ "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Latin 1 for XHTML//EN", ResourcePrefix + "xhtml-lat1.ent" },
{ "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Special for XHTML//EN", ResourcePrefix + "xhtml-special.ent" },
{ "http://www.w3.org/TR/xhtml1/DTD/-//W3C//ENTITIES Symbols for XHTML//EN", ResourcePrefix + "xhtml-symbol.ent" }
};
private static readonly Dictionary<string, Uri> _knownUris = new Dictionary<string, Uri>
{
{ "-//W3C//DTD XHTML 1.0 Strict//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") },
{ "-//W3C XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") },
{ "-//W3C//DTD XHTML 1.0 Transitional//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd") },
{ "-//W3C XHTML 1.0 Frameset//EN", new Uri("http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd") },
{ "-//W3C//DTD XHTML 1.1//EN", new Uri("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd") }
};
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
return _knownUris.ContainsKey(relativeUri) ? _knownUris[relativeUri] : base.ResolveUri(baseUri, relativeUri);
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if (absoluteUri == null)
{
throw new ArgumentNullException("absoluteUri");
}
if (_knownDtds.ContainsKey(absoluteUri.OriginalString))
{
string resourceName = _knownDtds[absoluteUri.OriginalString];
Assembly assembly = Assembly.GetAssembly(typeof(LocalXhtmlXmlResolver));
return assembly.GetManifestResourceStream(resourceName);
}
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}
Assembly.GetManifestResourceStream
加载它们;或者将它们作为本地文件放在与可执行文件相同的目录中。 - Pavel Minaev