如何在Perl中转义XML文档的文本?

时间:2009-07-16 13:57:48

标签: xml perl escaping

任何人都知道要在XML文档中转义文本的任何Perl模块吗?

我正在生成包含用户输入的文本的XML。我想正确处理文本,以便生成的XML格式正确。

9 个答案:

答案 0 :(得分:9)

我个人更喜欢XML::LibXML - 用于libxml的Perl绑定。其中一个优点 - 它使用了最快的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。当人们发现你做了什么时,这对你的健康会有害。

答案 1 :(得分:8)

我不确定为什么需要转义XML文件中的文本。如果您的文件包含:

<foo>x < y</foo>

尽管尖括号增加,但该文件是一个XML文件。 XML文件必须包含有效数据,如下所示:

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

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

因此,要么:

  1. 您不是要求在XML文件中转义数据。相反,您想要弄清楚如何将字符数据放在XML文件中,以便生成的文件是有效的XML;或

  2. 您在XML文件中有一些数据需要通过其他原因进行转义

  3. 注意详细说明?

答案 2 :(得分:8)

也可以使用XML :: Simple escape_value,但不建议在新程序中使用XML :: Simple。查看此帖子17436965。

可以使用正则表达式(从escape_value复制)完成手动转义:

$data =~ s/&/&amp;/sg;
$data =~ s/</&lt;/sg;
$data =~ s/>/&gt;/sg;
$data =~ s/"/&quot;/sg;

答案 3 :(得分:6)

使用XML::Code

来自CPAN

XML :: code escape()

通常,在渲染期间将对节点的任何内容进行转义(即,诸如“&amp;”的特殊符号将被相应的实体替换)。使用零参数调用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>

答案 4 :(得分:3)

XML::Entities

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

编辑:XML :: Entities仅对HTML实体进行编号。使用HTML::Entities encode_entities($ a)代替

答案 5 :(得分:3)

使用

XML ::发电机

  

需要XML :: Generator;

     

my $ xml = XML :: Generator-&gt; new(':pretty',escape =&gt;'always,'');

     

print $ xml-&gt; h1(“&amp;&lt;&gt; non-html plain text&lt;&gt;&amp;”);

将打印转义的标签内的所有内容(不与标记冲突)。

答案 6 :(得分:1)

按照Krish的建议检查XML :: Code后,我发现可以使用XML :: Code text()函数完成此操作。如,

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

传递'='会创建一个文本节点,打印时不包含标签。 注意:这仅适用于文本数据。它不会正确地逃脱属性。

答案 7 :(得分:0)

虽然您最好使用XML::LibXMLXML::Code之类的模块,但您可以将文本数据包装在CDATA部分中。您必须注意不要将]]>放入其中(此序列也不允许 CDATA部分之外!):

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

作为奖励,您的代码看起来会更加模糊! : - )

答案 8 :(得分:0)

对于需要处理各种特殊情况的程序,请务必使用官方库来执行此任务。但是,使用XML的module types

因此,对于您不想为其引入额外库的一次性任务,以下perl表达式应足够:

perl -pe 's/\&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&apos;/g'