【问题标题】:parse html with XML::LibXML while not touching entities在不接触实体的情况下使用 XML::LibXML 解析 html
【发布时间】:2011-10-09 03:47:33
【问题描述】:

我正在使用 XML::LibXML 来解析一大段 html,以更改所有锚元素的 title 属性。 问题是 XML::LibXML 篡改了未编码的实体,并将例如 '&' 更改为 '&'在 href 属性中的 url 参数中。

我如何告诉 XML::LibXML 不要尝试对这些实体进行编码或解码?

#!/usr/bin/perl -w

use strict;
use XML::LibXML;

my $parser = XML::LibXML->new(recover => 2);

my $html = '
<div>
    <span>this & that &amp; what?</span>
    <a title="link1" href="http://url.com/foo?a=1&b=2">Link1</a>
    <a title="link2" href="http://url.com/foo?a=1&b=2">Link2</a>
</div>';

my $doc = $parser->load_html(string => $html);

for my $node ($doc->findnodes('//*[@title]')) {
    $node->setAttribute('title', 'newtitle');
}

print $doc->toString(), "\n";

__END__

产生这个输出:

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div>
    <span>this &amp; that &amp; what?</span>
    <a title="newtitle" href="http://url.com/foo?a=1&amp;b=2">Link1</a>
    <a title="newtitle" href="http://url.com/foo?a=1&amp;b=2">Link2</a>
</div></body></html>

正如您将看到的那样,XML::LibXML 已经改变了 url,还改变了 span 标签内的文本!

【问题讨论】:

  • 嗯,基本上,您的输入不是有效的 XML。 Perl 有 HTML 解析器,也许试试其中之一? (虽然,它也不是有效的 HTML,但 HTML 解析器通常更宽容)
  • @derobert,XML::LibXML 的 load_html 是一个 HTML 解析器。
  • @derobert — 它也不是有效的 HTML。
  • 所以您想在保留错误的同时操作 HTML?我怀疑你会找到任何可以让你这样做的解析器。
  • @ikegami:由于 URL,它不是有效的 HTML。 &amp;b 不是有效实体。我很确定这在 XHTML 之前就是如此。另外,请记住 HTML 标准以奇怪的方式使用“应该”;例如,您只应该使用 <以避免与标签的开头混淆(HTML4 §5​​.3.2)。您需要检查 SGML 标准才能确定。

标签: perl xml-libxml


【解决方案1】:
正如您将看到的那样,XML::LibXML 已更改 url,以及 span 标签内的文本!

你错了。 URL 没有 改变。原始 HTML 和生成的 HTML 都生成相同的 URL (http://url.com/foo?a=1&amp;b=2)。 HTML 不同,但显示的文本不同。

span 中的文本也是如此。原始 HTML 和生成的 HTML 都生成相同的 URL (this &amp;amp; that &amp;amp; what?)。 HTML 不同,但 URL 不同。

据我所知,无法控制 XML::LibXML 的 toString 转义的字符。显然,它会选择转义 &amp;amp;,即使它在 HTML 技术上不是必需的。

为什么不呢?转义“&amp;amp;”并没有什么坏处。

«this &amp; that &amp;amp; what?» 和 «this &amp;amp; that &amp;amp; what?» 在 HTML 中的含义相同。

«href="http://url.com/foo?a=1&amp;amp;b=2"» 和 «href="http://url.com/foo?a=1&amp;b=2"» 在 HTML 中的含义相同。

PS——如果你想生成 HTML,你应该使用-&gt;toStringHTML(),而不是-&gt;toString()。后者生成 XML。

【讨论】:

  • 谢谢。人们通常不会对它们粘贴到 href、src(脚本)属性等中的 url 进行编码。因此,危害是人们在阅读源代码时必须用眼睛对编码的 url 参数进行解码。而且这使得在标题更新之前和之后对 html 进行比较变得更加困难……所以实际上有一些危害。
  • @user985995,现在大多数 HTML 都是 XHTML,它要求对“&amp;amp;”进行编码,所以人们必须习惯于看到&amp;amp;,所以你的论点并不真正保持任何水。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 1970-01-01
  • 2021-09-22
  • 2012-07-08
  • 1970-01-01
相关资源
最近更新 更多