我的XML文档包含封装为CDATA的其他XML文档,如下所示:
<mds>
<md>
<value>
<![CDATA[<?xml version="1.0" encoding="UTF-8"?><record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/">
<dc:title>some text containing &</dc:title></record>]]>
</value>
</md>
</mds>
我使用LibXML从中提取此XML和dc:title:
$dcrawData = <get the CDATA from above>;
$dcDOM = $::PRSR->load_xml(expand_entities => 0, string => $dcRawData);
$dcTitle = $dcDOM->findvalue("//dc:title");
然后我通过执行字符串替换将其插入另一个XML部分:
<mods:titleInfo>
<mods:title>some text containing &</mods:title>
</mods:titleInfo>
正如您所看到的,&amp; amp实体得到了扩展并成为单一&amp ;.这是一个问题,因为现在,生成的XML会生成解析错误,因为任何解析器都需要一个命名实体。
有没有办法在使用findvalue时阻止LibXML扩展命名实体或在使用值之前重新编码它们?其他记录中可能还有其他人。 expand_entities选项没有区别。
答案 0 :(得分:2)
好的,我想我找到了解决方案。 XML::Entities
将完成对字符串中实体进行重新编码的工作。
但是,我需要将编码的字符限制为少数,否则编码的字符串将包含xml解析器无法识别的实体。
所以目前我使用
$dcTitle = encode_entities($dcDOM->findvalue("//dc:title"),'&<>"');
仅编码&符号和一些特殊的xml字符。
答案 1 :(得分:1)
然后我通过执行字符串替换
将其插入另一个XML部分
别。如果您想将数据插入到XML文档中,那么您应该使用支持XML的知识API来处理任何必要的转义。
答案 2 :(得分:1)
然后我通过执行字符串替换
将其插入另一个XML部分
这是你做错的部分。您正在将文本插入XML而不将其转换为XML。 (这称为注入错误。)您需要转义&
,<
以及文档字符集之外的任何字符。
sub text_to_xml {
my ($s) = @_;
for ($s) {
s/&/&/g;
s/</</g;
s/"/"/g; # So it can be used for attributes too
s/'/'/g; # So it can be used for attributes too
}
return $s;
}
请勿忘记,您还需要根据文档的编码对其进行编码。