如何防止XML :: XPath在处理XML文件时获取DTD?

yog*_*man 12 xml perl dtd

我的XML(a.xhtml)就像这样开始

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
Run Code Online (Sandbox Code Playgroud)

我的代码就像这样开始

use XML::XPath;

use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => "a.xhtml");

my $nodeset = $xp->find('/html/body//table'); 
Run Code Online (Sandbox Code Playgroud)

它非常慢,事实证明它花了很多时间来获得DTD(http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd).

有没有办法在Perl XML :: family中显式声明HTTP代理服务器?我讨厌修改原始的a.xhtml文档,比如拥有DTD的本地副本.

mir*_*rod 15

XML :: XPath基于XML :: Parser.XML :: Parser中有一个选项是不使用LWP来解析外部实体(例如DTD).XML :: XPath允许您传递XML :: Parser对象,以用作解析器.

所以你可以这样写:

my $p = XML::Parser->new( NoLWP => 1);
my $xp= XML::XPath->new( parser => $p, filename => "a.xhtml");
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,您将丢失除数字和默认值之外的所有实体(>,<,&,'和").解析器不会抱怨,但它们将无声地消失(尝试在表中包含&​​alpha;并打印例如).

事实上,你可能不应该使用XML :: XPath,它不是主动维护的.

试试XML :: LibXML,如果你没有安装libxml2的问题,它的接口与XML :: XPath非常相似,因为它们都实现了DOM.XML :: LibXML也比XML :: XPath强大得多,并且启动速度更快.如果你想要一个基于expat/XML :: Parser的模块,你可能想要看一下XML :: Twig(那是公然的自我推销,因为我是模块的作者,对不起).另外对于HTML/dodgy XHTML,你可以使用HTML :: TreeBuilder,它加上HTML :: TreeBuilder :: XPath(也是我),支持XPath.