问题:我需要一个由 UTF8 “完全编码”的 XML 文件;也就是说,没有实体表示符号,所有符号都由 UTF8 编码,除了 XML 保留的仅有的 3 个符号,“&”(amp)、“<”(lt)和“>”(gt)。而且,我需要一个能够快速完成的内置函数:将实体转换为真正的 UTF8 字符(不会破坏我的 XML)。
PS:这是一个“现实世界的问题”(!);例如,在PMC/journals中,有 280 万篇科学文章以特殊的 XML DTD(也称为JATS 格式)进行编码...要处理为“通常的 XML-UTF8-text”,我们需要从数字实体更改为 UTF8字符。
尝试的解决方案:此任务的自然函数是html_entity_decode,但它破坏了 XML 代码 (!),转换了保留的 3 个 XML 保留符号。
说明问题
认为
$xmlFrag ='<p>Hello world!    Let A<B and A=∬dxdy</p>';
其中实体 160 (nbsp) 和 x222C (双整数) 必须转换为 UTF8,而 XML-reserved 则lt
不需要。XML 文本将(转换后),
$xmlFrag = '<p>
世界你好!令 A <
B 和 A=∬dxdy </p>
';
文本“A<B”需要一个 XML 保留字符,因此必须保持为A<B
.
沮丧的解决方案
我尝试使用html_entity_decode
来解决(直接!)问题......所以,我将我的 PHP 更新到 v5.5 以尝试使用该ENT_XML1
选项,
$s = html_entity_decode($xmlFrag, ENT_XML1, 'UTF-8'); // not working
// as I expected
也许另一个问题是,“为什么没有其他选择可以做我期望的事情?” ——这对许多其他 XML 应用程序(!)很重要,不仅对我来说。
我不需要解决方法作为答案...好吧,我展示了我丑陋的功能,也许它可以帮助您理解问题,
function xml_entity_decode($s) {
// here an illustration (by user-defined function)
// about how the hypothetical PHP-build-in-function MUST work
static $XENTITIES = array('&','>','<');
static $XSAFENTITIES = array('#_x_amp#;','#_x_gt#;','#_x_lt#;');
$s = str_replace($XENTITIES,$XSAFENTITIES,$s);
//$s = html_entity_decode($s, ENT_NOQUOTES, 'UTF-8'); // any php version
$s = html_entity_decode($s, ENT_HTML5|ENT_NOQUOTES, 'UTF-8'); // PHP 5.3+
$s = str_replace($XSAFENTITIES,$XENTITIES,$s);
return $s;
} // you see? not need a benchmark:
// it is not so fast as direct use of html_entity_decode; if there
// was an XML-safe option was ideal.
PS:在此答案后更正。必须是ENT_HTML5
标志,以便真正转换所有命名实体。