2009-07-16 42 views
2

任何知道任何Perl模块转义XML文档中的文本?如何在Perl中转义XML文档的文本?

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

+3

什么样的“逃离”你指的是? – 2009-07-16 14:00:05

+1

您是否试图手动创建XML输出? – 2009-07-16 17:31:47

回答

7

我个人比较喜欢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。当人们发现你所做的事情时,它会对你的健康有害。

6

使用XML::Code

从CPAN

XML ::代码逃逸()

通常情况下,节点的任何内容将在再现期间被转义(即如“&”将用相应实体取代特殊符号)。呼叫逃生()零参数来防止它:

 my $p = XML::Code->('p'); 
     $p->set_text ("—"); 
     $p->escape (0); 
     print $p->code(); # prints <p>&#8212;</p> 
     $p->escape (1); 
     print $p->code(); # prints <p>&amp;#8212;</p> 
3

XML::Entities

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

编辑:XML ::实体仅numifies HTML实体。使用HTML::Entities encode_entities($ a)代替

+0

XML :: Entities :: numify似乎只是将命名的XML实体转换为数字XML实体。 – coldeq 2009-07-16 23:12:32

+0

你说得对,我的错。可以使用HTML :: Entities和encode_entities来代替。 – hovenko 2009-07-17 10:07:05

10

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

<foo>x < y</foo> 

该文件尽管尖括号泛滥的XML文件。一个XML文件必须包含有效的数据意味着这样的事情:

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

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

因此,无论是:

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

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

有意详细说明一下吗?

+0

对那些低估的人:我上面说的究竟是什么错误? – 2009-07-16 15:24:04

+2

当你提醒他们他们的伪XML实际上不是真正的XML时,人们会生气。这很有趣...而且很伤心。无论如何,我upvoted你:) – jrockway 2009-07-16 20:29:45

1

在检查出由Krish推荐的XML :: Code后,我发现可以使用XML ::代码text()函数完成此操作。例如,

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

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

3

使用

XML ::发电机

需要XML ::发生器;

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

print $ xml-> h1(“& <>非html纯文本<> &”);

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

0

虽然您最好使用XML::LibXMLXML::Code这样的模块,但您可以将文本数据封装在CDATA部分中。你只能小心不要把]]>在它(这个顺序也不允许 CDATA节!):

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

至于奖金你的代码看起来更Perlish的混淆! :-)

6

也可以使用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;