разбирать HTML с XML :: LibXML, не касаясь сущностей - PullRequest
1 голос
/ 09 октября 2011

Я использую XML :: LibXML для разбора фрагмента html, чтобы изменить атрибут title всех элементов привязки.Проблема заключается в том, что XML :: LibXML изменяет некодированные объекты и меняет, например, '&' на '&' в параметрах URL в атрибутах href.

Как мне указать 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!

1 Ответ

2 голосов
/ 09 октября 2011
Как вы увидите, XML :: LibXML изменил URL, а также текст внутри тега span!

Вы ошибаетесь. URL не изменился. И исходный HTML, и сгенерированный HTML создают один и тот же URL (http://url.com/foo?a=1&b=2). HTML-код другой, но отображаемый текст - нет.

То же самое относится и к тексту в промежутке. И исходный HTML, и сгенерированный HTML создают один и тот же URL (this & that & what?). HTML отличается, но URL не.

Насколько мне известно, нет способа контролировать, какие символы XML :: LibXML экранируют toString. Очевидно, он выбирает экранирование &amp;, даже если это технически не требуется в HTML.

Есть почему? Нет никакого вреда в том, что "&" сбежал.

"this & that &amp; what?" и "this &amp; that &amp; what?" означают одно и то же в HTML.

"href="http://url.com/foo?a=1&amp;b=2"" и "href="http://url.com/foo?a=1&b=2"" означают одно и то же в HTML.

PS & mdash; Если вы хотите создать HTML, вы должны использовать ->toStringHTML(), а не ->toString(). Последний производит XML.

...