PHP没有XML安全实体解码功能?没有一些xml_entity_decode?
问题:我需要一个UTF8“完全编码”的
XML文件;也就是说,没有实体代表符号,UTF8所包含的所有符号,除了仅有3个XML保留的符号外,“&” (amp),“<” (lt)和“>” (GT).并且,我需要一个快速执行的内置函数:将实体转换为真正的UTF8字符(不破坏我的XML).
?PS:这是一个“现实世界的问题”(!);例如,在 PMC/journals,有数以万计的科学文章与 a special XML DTD相关(也被称为 JATS format)…要处理为“通常的XML-UTF8文本”,我们需要从数字实体更改为UTF8字符. 经过尝试的解决方案:此任务的自然功能是html_entity_decode,但它会破坏XML代码(!),转换保留的3个XML保留符号. 说明问题 假设 $xmlFrag ='<p>Hello world!    Let A<B and A=∬dxdy</p>'; 实体160(nbsp)和x222C(双积分)必须转换为UTF8,而XML保留的不是. XML文本将(转换后), $xmlFrag =’< p> Hello world!设A& lt; B和A =?dxdy< / p>‘; 文本“A< B”需要XML保留字符,因此必须保持为A& lt; 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:在this answer之后更正.必须是ENT_HTML5标志,用于转换really all named entities. 解决方法
这个问题正在逐时创造一个“错误答案”(见答案).这可能是因为人们没有注意,并且因为没有回答:缺乏PHP内置解决方案.
…所以,让我们重复我的解决方法(这不是答案!),不要造成更多混乱: 最好的解决方法 请注意: >下面的函数xml_entity_decode()是最好的(超过任何其他)解决方法. function xml_entity_decode($s) { // illustrating how a (hypothetical) PHP-build-in-function MUST work static $XENTITIES = array('&',$s); $s = html_entity_decode($s,'UTF-8'); // PHP 5.3+ $s = str_replace($XSAFENTITIES,$s); return $s; } 要测试并证明您有更好的解决方案,请先使用以下简单的benckmark进行测试: $countBchMk_MAX=1000; $xml = file_get_contents('sample1.xml'); // BIG and complex XML string $start_time = microtime(TRUE); for($countBchMk=0; $countBchMk<$countBchMk_MAX; $countBchMk++){ $A = xml_entity_decode($xml); // 0.0002 /* 0.0014 $doc = new DOMDocument; $doc->loadXML($xml,LIBXML_DTDLOAD | LIBXML_NOENT); $doc->encoding = 'UTF-8'; $A = $doc->saveXML(); */ } $end_time = microtime(TRUE); echo "n<h1>END $countBchMk_MAX BENCKMARKs WITH ",($end_time - $start_time)/$countBchMk_MAX," seconds</h1>"; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |