xmllint 无法验证 XHTML 1.0 过渡文件

xmllint fails to validate XHTML 1.0 Transitional file

提问人: 提问时间:5/16/2016 更新时间:5/16/2016 访问量:1935

问:

在 Debian Jessie GNU/Linux 上重现的步骤。

检查版本:xmllint

$ xmllint --version
xmllint: using libxml version 20901
   compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib Lzma 

制作一个 XHTML 1.0 过渡文件,将其另存为:example.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>A title</title>
</head>

<body>
Some content
</body>

</html>

注意:将 example.xhtml 的内容粘贴到 W3C 验证器中会产生“此文档已成功检查为 XHTML 1.0 过渡!”,因此在使用 .xmllint

xmllint 联机验证

尽管计算机可以访问 Internet,但此操作仍会失败:

$ xmllint --noout --valid example.xhtml
example.xhtml:1: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
                                                                               ^
example.xhtml:2: validity error : Validation failed: no DTD found !
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
                                                                  ^

xmllint 脱机验证

安装 XHTML 1.0 DTD 和实体文件

$ wget -qO- https://www.w3.org/TR/xhtml1/xhtml1.tgz | tar xvz
xhtml1-20020801/
xhtml1-20020801/W3C-REC.css
xhtml1-20020801/xhtml.css
xhtml1-20020801/logo-REC.png
xhtml1-20020801/w3c_home.png
xhtml1-20020801/wcag1AAA.png
xhtml1-20020801/acks.html
xhtml1-20020801/Cover.html
xhtml1-20020801/definitions.html
xhtml1-20020801/diffs.html
xhtml1-20020801/dtds.html
xhtml1-20020801/guidelines.html
xhtml1-20020801/introduction.html
xhtml1-20020801/issues.html
xhtml1-20020801/normative.html
xhtml1-20020801/Overview.html
xhtml1-20020801/prohibitions.html
xhtml1-20020801/references.html
xhtml1-20020801/xhtml1-diff.html
xhtml1-20020801/DTD/
xhtml1-20020801/DTD/xhtml-lat1.ent
xhtml1-20020801/DTD/xhtml-special.ent
xhtml1-20020801/DTD/xhtml-symbol.ent
xhtml1-20020801/DTD/xhtml.soc
xhtml1-20020801/DTD/xhtml1-frameset.dtd
xhtml1-20020801/DTD/xhtml1-strict.dtd
xhtml1-20020801/DTD/xhtml1-transitional.dtd
xhtml1-20020801/DTD/xhtml1.dcl
xhtml1-20020801/xhtml1.ps
xhtml1-20020801/xhtml1.pdf

仍然失败:

$ xmllint --noout --dtdvalid xhtml1-20020801/DTD/xhtml1-transitional.dtd example.xhtml 
example.xhtml:1: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
                                                                               ^

同样,如果使用以下选项:--nonet

$ xmllint --noout --nonet --dtdvalid xhtml1-20020801/DTD/xhtml1-transitional.dtd example.xhtml 
I/O error : Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
example.xhtml:1: warning: failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
                                                                               ^

问题

我有两个问题:

  1. 为什么这些验证尝试都没有成功?
  2. 第二个似乎失败了,因为尽管使用了该选项,但仍然尝试访问,因为它在 中引用。有没有办法告诉忽略该引用并改用本地 DTD(例如,已经存储在 ?--dtdvalidxmllinthttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtdexample.xhtmlxmllintxhtml1-20020801/DTD/xhtml1-transitional.dtd
Linux 验证 xmllint xhtml-transitional

评论


答:

0赞 user82216 5/16/2016 #1

似乎最简单的解决方法是:

$ sudo apt-get install w3c-dtd-xhtml

这将在本地安装相关的 DTD。此后,验证成功:

$ xmllint --noout --valid example.xhtml
$

但是,尽管这允许我验证XHTML文件,但它并没有真正回答问题。因此,我不会将这个问题标记为“已回答”,希望有人能提供确实回答他们的答案。

评论

0赞 Mr Lister 5/16/2016
我不熟悉 xmllint,所以我不打算发布完整的答案,但显然 xmllint 只有在本地确实有可用的 DTD 时才能兑现该选项。另请参阅此线程--nonet
0赞 Mr Lister 5/16/2016
这仍然不能解释为什么即使你允许 xmllint 出去并从网络获取 DTD,你也会收到错误。你确定 xmllint 可以访问网络吗?你没有某种限制访问的防火墙或其他东西吗?
0赞 5/16/2016
@MrLister,谢谢。“[显然] xmllint 只有在本地确实有可用的 DTD 时才能遵循 --nonet 选项。”事实上。从我使用的示例中可以看出,我使用 指定了本地 DTD。“你确定 xmllint 可以访问网络吗?”我没有设置或检测到任何阻碍 xmllint 访问 Internet 的障碍。正如你在我的例子中看到的,wget在相同的环境中工作正常(我可以确认它不需要被列入白名单等)。--nonet--dtdvalid