【问题标题】:xmllint fails to validate XHTML 1.0 Transitional filexmllint 无法验证 XHTML 1.0 过渡文件
【发布时间】:2016-09-11 13:30:02
【问题描述】:

在 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 

通过将其保存为example.xhtml 来制作一个 XHTML 1.0 过渡文件:

<!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 Validator 中会产生“此文档已成功检查为 XHTML 1.0 Transitional!”,因此在使用 xmllint 时也应进行验证。

xmllint 在线验证

尽管计算机可以访问互联网,但此操作失败:

$ 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 DTDs and entity files:

$ 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. 第二个似乎失败了,因为尽管使用了--dtdvalid 选项,xmllint 仍然尝试访问http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd,因为它在example.xhtml 中被引用。有什么方法可以告诉xmllint 忽略该引用,而是使用本地DTD(例如,已经存储在xhtml1-20020801/DTD/xhtml1-transitional.dtd 的那个?

【问题讨论】:

    标签: linux validation xhtml xmllint xhtml-transitional


    【解决方案1】:

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

    $ sudo apt-get install w3c-dtd-xhtml
    

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

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

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

    【讨论】:

    • 我对 xmllint 不熟悉,所以我不会发布完整的答案,但显然 xmllint 只能在本地确实有可用的 DTD 时才能兑现 --nonet 选项。另请参阅this thread
    • 即使您确实允许 xmllint 出去并从网上获取 DTD,这仍然无法解释为什么您会收到错误。你确定 xmllint 可以访问网络吗?你没有某种限制访问的防火墙吗?
    • @MrLister,谢谢。 “[显然] xmllint 只有在本地确实有可用的 DTD 时才能使用 --nonet 选项。” 确实如此。从我使用--nonet 的示例中您将看到,我使用--dtdvalid 指定了一个本地DTD。 “您确定 xmllint 可以上网吗?”​​ 我没有设置或检测到 xmllint 访问 Internet 的任何障碍。正如您在我的示例中看到的那样,wget 在相同的环境中工作正常(我可以确认它不需要被列入白名单等)。
    猜你喜欢
    • 1970-01-01
    • 2012-05-26
    • 2010-09-20
    • 2011-01-31
    • 2011-05-08
    • 1970-01-01
    • 2012-05-16
    • 2013-03-23
    • 2011-03-15
    相关资源
    最近更新 更多