任何人都知道要在XML文档中转义文本的任何Perl模块吗?
我正在生成包含用户输入的文本的XML。我想正确处理文本,以便生成的XML格式正确。
答案 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 < y</foo>
或
<foo><![CDATA[x < y]]></foo>
因此,要么:
您不是要求在XML文件中转义数据。相反,您想要弄清楚如何将字符数据放在XML文件中,以便生成的文件是有效的XML;或
您在XML文件中有一些数据需要通过其他原因进行转义。
注意详细说明?
答案 2 :(得分:8)
也可以使用XML :: Simple escape_value,但不建议在新程序中使用XML :: Simple。查看此帖子17436965。
可以使用正则表达式(从escape_value复制)完成手动转义:
$data =~ s/&/&/sg;
$data =~ s/</</sg;
$data =~ s/>/>/sg;
$data =~ s/"/"/sg;
答案 3 :(得分:6)
使用XML::Code。
来自CPAN
XML :: code escape()
通常,在渲染期间将对节点的任何内容进行转义(即,诸如“&amp;”的特殊符号将被相应的实体替换)。使用零参数调用escape()以防止它:
my $p = XML::Code->('p');
$p->set_text ("—");
$p->escape (0);
print $p->code(); # prints <p>—</p>
$p->escape (1);
print $p->code(); # prints <p>&#8212;</p>
答案 4 :(得分:3)
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 > < & " ' "
传递'='会创建一个文本节点,打印时不包含标签。 注意:这仅适用于文本数据。它不会正确地逃脱属性。
答案 7 :(得分:0)
虽然您最好使用XML::LibXML
或XML::Code
之类的模块,但您可以将文本数据包装在CDATA部分中。您必须注意不要将]]>
放入其中(此序列也不允许在 CDATA部分之外!):
$text =~ s/\]\]>/]]>]]><![CDATA[/;
$text = "<![CDATA[$text]]>";
$xml = "<foo>$text</foo>";
作为奖励,您的代码看起来会更加模糊! : - )
答案 8 :(得分:0)
对于需要处理各种特殊情况的程序,请务必使用官方库来执行此任务。但是,使用XML的module types。
因此,对于您不想为其引入额外库的一次性任务,以下perl表达式应足够:
perl -pe 's/\&/\&/g; s/</\</g; s/>/\>/g; s/"/\"/g; s/'"'"'/\'/g'