- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我正在尝试对 xhtml 文档执行 xpath 查询。使用 .NET 3.5。
文档看起来像这样:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
....
</head>
<body>
...
</body>
</html>
因为文档包含各种字符实体(
等),我需要使用 DTD,以便使用 XmlReader 加载它.所以我的代码看起来像这样:
var s = File.OpenRead(fileToRead)
var reader = XmlReader.Create(s, new XmlReaderSettings{ ProhibitDtd=false });
但是当我运行它时,它返回
An error has occurred while opening external DTD 'http://www.w3.org/TR/xhtml1-transitional.dtd': The remote server returned an error: (503) Server Unavailable.
现在,我知道为什么我会收到 503 错误。 W3C explained it very clearly .
我见过人们只是禁用 DTD 的“解决方法”。这就是 ProhibitDtd=true
可以做的,它消除了 503 错误。
但在我的例子中,这会导致其他问题——应用程序没有获得实体定义,因此不是格式正确的 XML。如何在不访问 w3.org 网站的情况下使用 DTD 进行验证并获取实体定义?
我认为 .NET 4.0 有一个很好的内置功能来处理这种情况:XmlPreloadedResolver .但我需要 .NET 3.5 的解决方案。
相关:
- java.io.IOException: Server returned HTTP response code: 503
最佳答案
答案是,我必须提供我自己的XmlResolver .我认为这不是 .NET 3.5 的内置功能。真令人费解。令人困惑的是我花了这么长时间才发现这个问题。同样令人困惑的是我找不到其他人已经解决了这个问题?
好的,所以.. XmlResolver。我创建了一个新类,派生自 XmlResolver 并覆盖了三个关键内容:Credentials (set)、ResolveUri 和 GetEntity。
public sealed class XhtmlResolver : XmlResolver
{
public override System.Net.ICredentials Credentials
{
set { throw new NotSupportedException();}
}
public override object GetEntity(Uri absoluteUri, string role, Type t)
{
...
}
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
...
}
}
关于这些东西的文档非常简陋,所以我会告诉你我学到了什么。这个类的操作是这样的:XmlReader首先调用ResolveUri,然后,给定一个解析的Uri,然后调用GetEntity。该方法应返回类型 t 的对象(作为参数传递)。我只看到它请求 System.IO.Stream。
我的想法是使用 csc.exe /resource
选项将 DTD 的本地副本及其 XHTML1.0 的依赖项嵌入到程序集中,然后检索该资源的流。
private System.IO.Stream GetStreamForNamedResource(string resourceName)
{
Assembly a = Assembly.GetExecutingAssembly();
return a.GetManifestResourceStream(resourceName);
}
很简单。这是从 GetEntity() 调用的。
但我可以改进这一点。我没有将 DTD 嵌入纯文本,而是先将它们压缩。然后像这样修改上面的方法:
private System.IO.Stream GetStreamForNamedResource(string resourceName)
{
Assembly a = Assembly.GetExecutingAssembly();
return new System.IO.Compression.GZipStream(a.GetManifestResourceStream(resourceName), System.IO.Compression.CompressionMode.Decompress);
}
该代码打开嵌入式资源的流,并返回配置为解压缩的 GZipStream。读者得到明文 DTD。
我想做的是只解析来自 Xhtml 1.0 的 DTD 的 URI。所以我编写了 ResolveUri 和 GetEntity 来查找那些特定的 DTD,并且只对它们做出肯定的响应。
对于带有DTD语句的XHTML文档,流程是这样的;
XmlReader 使用 XHTML DTD 的公共(public) URI 调用 ResolveUri,即 "-//W3C//DTD XHTML 1.0 Transitional//EN"
。如果 XmlResolver 可以解析,它应该返回...一个有效的 URI。如果它不能解决,它应该抛出。我的实现只是抛出公共(public) URI。
XmlReader 然后使用 DTD 的系统标识符调用 ResolveUri,在本例中为 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
。在这种情况下,XhtmlResolver 返回一个有效的 Uri。
XmlReader 然后使用该 URI 调用 GetEntity。 XhtmlResolver 获取嵌入的资源流并将其返回。
依赖项也会发生同样的事情 - xhtml_lat1.ent,等等。为了让解析器工作,所有这些东西都需要嵌入。
是的,如果 Resolver 无法解析 URI,它会抛出异常。据我所知,这没有正式记录。似乎有点意外。 (严重违反 the principle of least astonishment )。相反,如果 ResolveUri 返回 null,则 XmlReader 将对 null URI 调用 GetEntity,这……啊,没希望了。
这对我有用。它应该适用于 任何 从 .NET 对 XHTML 进行 XML 处理的人。如果您想在自己的应用程序中使用它,grab the DLL .该 zip 包含完整的源代码。根据 MS Public License 获得许可.
您可以将它插入您的 XML 应用程序中,这些应用程序使用 XHTML。像这样使用它:
// for an XmlDocument...
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.XmlResolver = new Ionic.Xml.XhtmlResolver();
doc.Load(xhtmlFile);
// for an XmlReader...
var xmlReaderSettings = new XmlReaderSettings
{
ProhibitDtd = false,
XmlResolver = new XhtmlResolver()
};
using (var stream = File.OpenRead(fileToRead))
{
XmlReader reader = XmlReader.Create(stream, xmlReaderSettings);
while (reader.Read())
{
...
}
关于.net - 打开外部 DTD(w3.org、xhtml1-transitional.dtd)时发生错误。 503 服务器不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2558021/
是否可以在我的 DTD 中声明一个可以有任何名称的元素?到目前为止,我了解到 ANY 只能用于以下数据类型: 任何帮助将不胜感激。 --阿里 最佳答案 不,ANY 关键字仅适用于元素的类别。无论如何
我得到了以下 DTD: 有人问我: This DTD is recursive! How does the recursion end? 嗯……我不明白为什么要递归?唯一递归的接缝
是否可以在另一个 DTD 中包含一个 DTD? (我的意思不是将第二个 DTD 复制并粘贴到第一个 DTD 中。我的意思是在第一个 DTD 中有一个指向第二个 DTD 的指针。) 最佳答案 是的,这是
我知道我应该将所有 html 元素放在 body 标签中,但我需要将两个隐藏的输入放在 html dtd 之上。我猜它不会使我的 html 文件成为标准文件,但有那么糟糕吗?我有以下代码。 什么
在输入文档中没有 any 文档类型的情况下,如何在解析文档时强制 SAX 解析器(特别是 Java 中的 Xerces)使用 DTD?这可能吗? 以下是我的场景的更多详细信息: 我们有一堆符合相同 D
我正在尝试通过 .dtd 验证 xml 文件。我写了这个验证器: public bool Validation(XmlDocument xmlDoc) { var xm
我有一个处理 HTTP 请求的网络服务。它收到的文档有一个嵌入的 DOCTYPE,指定了一个 .dtd 文件。我希望使用更新的 XML 架构验证文件,以便在更新的设备连接到我的服务时使用。 我可以成功
我在弄清楚 HXT 为何要替换我的 DTD 时遇到了一些麻烦。首先,这是我要解析的输入文件: foo foo 这是我得到的输出: foo
我能否定义一个 DTD,使其中的元素具有在外部 DTD 中定义的结构?我的意思是类似于以下内容(这是一个我知道在某些方面无效的示例,但希望它能让您了解我在寻找什么): 此处的尝试是表示消息
如何使用外部 DTD 文件来验证我的 XML 文件? DTD 将位于某些 url 上,例如http://localhost/example.dtd 并且 DTD 未在 XML 文件中引用,因此我需要在
以下声明出现在 html 4.01 dtds 中 (参见 http://www.w3.org/TR/REC-html40/sgml/dtd.html 在 strict.dtd 和 loose.dtd
我想知道是否有一个程序可以读取 DTD 规范,使用规范创建表单或控制台提示,使用表单/提示获取用户输入的数据,然后根据输入的数据编写 XML 文档. 有这样的程序吗? 例如,想象一下: [开始想象]
我想使用 JAXB 从 dtd 文件生成 Java 类。 dtd 看起来像这样: 使
我正在尝试对 xhtml 文档执行 xpath 查询。使用 .NET 3.5。 文档看起来像这样: .... ... 因为文档包含各种字符实体( 等),我
我发现了很多这样的例子: public static boolean validateXMLSchema(String xsdPath, String xmlPath){ tr
大家好: 我想获得网络浏览器的实际高度,但我对 W3C DTD HTML 4.01 和 //W3C 有一些困惑//DTC XHTML 1.0,以下是我的问题详情: 如果我在页眉顶部使用 W3C DTD
我正在使用 Java 6 并尝试解析以 开头的格式良好的文档 我下载了实体 DTD“http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”,并将其放置在
这个问题已经有答案了: Xerces error: org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl (2 个回答) 已关闭 5 年前。 在 jboss w
这个问题在这里已经有了答案: Xerces error: org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl (2 个答案) 关闭 5 年前。 我正在使用
在下面的代码中: private Document transformDoc(Source source) throws TransformerException, IOException {
我是一名优秀的程序员,十分优秀!