Как я могу избежать текста для XML-документа в Perl? - PullRequest
3 голосов
/ 16 июля 2009

Кто-нибудь знает какой-нибудь модуль Perl для экранирования текста в XML-документе?

Я генерирую XML, который будет содержать текст, введенный пользователем. Я хочу правильно обработать текст, чтобы полученный XML был правильно сформирован.

Ответы [ 9 ]

9 голосов
/ 17 июля 2009

Я лично предпочитаю XML :: LibXML - привязка Perl для libxml. Один из плюсов - он использует одну из самых быстрых доступных библиотек обработки XML. Вот пример для создания текстового узла:

use XML::LibXML;
my $doc = XML::LibXML::Document->new('1.0',$some_encoding);
my $element = $doc->createElement($name);
$element->appendText($text);
$xml_fragment = $element->toString();
$xml_document = $doc->toString();

И никогда не создавайте XML вручную. Это будет вредно для вашего здоровья, когда люди узнают, что вы сделали.

8 голосов
/ 04 октября 2013

Можно также использовать XML :: Simple escape_value, но использование XML :: Simple не рекомендуется для новых программ. Смотрите этот пост 17436965.

Экранирование вручную можно выполнить с помощью регулярного выражения (скопировано из escape_value):

$data =~ s/&/&/sg;
$data =~ s/</&lt;/sg;
$data =~ s/>/&gt;/sg;
$data =~ s/"/&quot;/sg;
8 голосов
/ 16 июля 2009

Я не уверен, почему вам нужно экранировать текст, который находится в файле XML. Если ваш файл содержит:

<foo>x < y</foo>

Файл не XML-файл, несмотря на распространение угловых скобок. Файл XML должен содержать действительные данные, означающие что-то вроде этого:

<foo>x &lt; y</foo>

или

<foo><![CDATA[x < y]]></foo>

Следовательно, либо:

  1. Вы не запрашиваете экранирование данных в файле XML. Скорее, вы хотите выяснить, как поместить символьные данные в файл XML, чтобы полученный файл был действительным XML; или

  2. У вас есть некоторые данные в файле XML, которые необходимо экранировать по другим причинам .

Хотите уточнить?

6 голосов
/ 16 июля 2009

Использование XML :: Код .

Из CPAN

XML :: код escape ()

Обычно любое содержимое узла будет экранировано во время рендеринга (т. Е. Специальные символы, такие как '&', будут заменены соответствующими объектами). Вызовите escape () с нулевым аргументом, чтобы предотвратить это:

        my $p = XML::Code->('p');
        $p->set_text ("&#8212;");
        $p->escape (0);
        print $p->code(); # prints <p>&#8212;</p>
        $p->escape (1);
        print $p->code(); # prints <p>&amp;#8212;</p>
3 голосов
/ 25 октября 2009

Использование

XML :: Generator

требуется XML :: Generator;

my $ xml = XML :: Generator-> new (': pretty', escape => 'всегда, apos');

print $ xml-> h1 ("& <> не-html обычный текст <> &");

, который будет печатать весь контент внутри экранированных тегов (не конфликтует с разметкой).

3 голосов
/ 16 июля 2009

XML :: Entities

use XML::Entities;
my $a_encoded = XML::Entities::numify('all', $a);

Редактировать: XML :: Entities только нумерует HTML-сущности. Используйте HTML :: Entities encode_entities ($ a) вместо

1 голос
/ 17 июля 2009

После проверки XML :: Code в соответствии с рекомендациями Krish я обнаружил, что это можно сделать с помощью функции XML :: Code text(). Например.,

use XML::Code;
my $text = new XML::Code('=');
$text->set_text(q{> & < " ' "});
print $text->code(); # prints &gt; &lt; &amp; " ' "

Передача '=' создает текстовый узел, который при печати не содержит тегов. Примечание: это работает только для текстовых данных. Это не будет правильно экранировать атрибуты.

0 голосов
/ 26 апреля 2019

Для программ, которые должны обрабатывать каждый особый случай, непременно используйте для этой задачи официальную библиотеку. Однако теоретически есть только 5 символов, которые нужно экранировать в XML.

Таким образом, для одноразовых предложений, для которых вы не хотите использовать дополнительную библиотеку, должно быть достаточно следующего выражения perl:

perl -pe 's/\&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&apos;/g'
0 голосов
/ 17 марта 2011

Хотя вам лучше использовать такой модуль, как XML::LibXML или XML::Code, вы можете поместить текстовые данные в раздел CDATA. Вы должны только позаботиться о том, чтобы не вводить ]]> (эта последовательность также запрещена за пределами разделов CDATA!):

$text =~ s/\]\]>/]]>]]&gt;<![CDATA[/;
$text = "<![CDATA[$text]]>";
$xml = "<foo>$text</foo>"; 

В качестве бонуса ваш код будет выглядеть более запутанным! : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...