2016-10-13 11 views
0

我正在测试一些代码并解析了XML。为了进行简单的测试,我请求了/我的本地主机,响应是我的Apache2默认页面。 到目前为止,这么好。Perl-XML :: LibXML:Apache2上的错误解析性能默认页面

响应是XHTML,因此是XML。所以我拿它来解析(〜11K的大小)。

XML::LibXML->load_xml (string => $response); 

它需要大约16秒,直到它完成没有错误。

如果我给它一个其他xml文件,如果需要0时间,它的大小加倍。

所以...为什么?

Apache/2.4.10 
Debian/8.6 
XML::LibXML/2.0128 

编辑

我需要一提的是我删除了非XML HTTP头。

所以串

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

开始,以

</html> 

编辑结束

链接:http://s000.tinyupload.com/index.php?file_id=88759644475809123183

+0

你可以分享'$ response'的内容,以便我们可以在我们结束时检查它吗? –

+0

它是没有HTTP头的Apache2默认页面的输出。大小〜11k。我将在我的文章中加入一个tinyupload链接。 – chris01

回答

1

一种可能性是,每次解析文档解析器关闭从W3C加载DTD。您可以根据您的平台使用strace或类似的工具来确认。

DTD包含(除其他之外)命名的实体定义,它将字符串&nbsp;映射到字符U+00A0。所以为了解析HTML文档,解析器确实需要DTD,但每次都通过HTTP获取它显然不是一个好主意。

一种方法是在本地安装DTD的副本并使用它。在Debian/Ubuntu系统上,您可以安装w3c-dtd-xhtml软件包,该软件包还设置适当的XML目录条目以允许libxml找到它。

另一种方法是使用XML::LibXML->load_html代替XML::LibXML->load_xml。在HTML解析模式下,解析器对标记错误更为宽容,我认为也总是使用DTD的本地副本。

解析器还提供了一些选项,允许您指定自己的处理程序例程来检索参考URI。

+0

的确,这是网络。我原本没想到。谢谢! – chris01

+0

要停止通过网络加载DTD,请将['no_network'](https://metacpan.org/pod/distribution/XML-LibXML/lib/XML/LibXML/Parser.pod#no_network)分析器选项设置为1 (通常推荐)或['load_ext_dtd'](https://metacpan.org/pod/distribution/XML-LibXML/lib/XML/LibXML/Parser.pod#load_ext_dtd)为0。 – nwellnhof