2017-05-26 46 views
1

我正在向外部供应商发送XML文档,其中一个解析我们的XML时遇到问题,因为XML内容中存在单引号和双引号。我知道,根据官方的XML规范,只有在属性中使用这些规范时才需要转义,但我认为扩展PHP的SimpleXMLElement以使其避免引号并不困难。此情况并非如此。我第一次尝试是这样的:扩展PHP的SimpleXMLElement

<?php 
class BetterXMLElement extends SimpleXMLElement 
{ 
    public function __set($name, $value) 
    { 
     echo "called __set with $name and $value"; 
     $this->addChild($name, $value); 
    } 

    public function addChild($name, $value=null, $ns=null) 
    { 
     $new_value = strtr($value, [ 
      '&' => '&amp;', 
      '"' => '&quot;', 
      "'" => '&apos;', 
     ]); 
     echo "New Value: $new_value\n"; 
     parent::addChild($name, $new_value, $ns); 
    } 
} 

$xml = new BetterXMLElement('<?xml version="1.0" encoding="UTF-8"?><TRANSACTION></TRANSACTION>'); 
$xml->COST = "apos: ', amp: &, quot: \""; 
$xml->addChild('PRODUCT', "apos: ', amp: &, quot: \""); 
echo $xml->asXML(); 

上面的代码输出:

New Value: apos: &apos;, amp: &amp;, quot: &quot; 
<?xml version="1.0" encoding="UTF-8"?> 
<TRANSACTION><COST>apos: ', amp: &amp;, quot: "</COST><PRODUCT>apos: ', amp: &amp;, quot: "</PRODUCT></TRANSACTION> 

这一点让我的是:

  1. __set回声不会被调用,因为我会期待它在我设定成本时。为什么这不起作用?
  2. 我在设置PRODUCT时会调用addChild上的override,但在调用asXML时,引号的HTML实体会变回。它为什么这样工作?有没有办法禁用它?
+0

显示如何重现问题的一些代码示例在这里会很有帮助。 –

+0

@JakubMatczak好点,我添加了一些示例用法和输出! –

+0

SimpleXMLElement类不是普通类。它看起来像一个班,但它以非常规方式做了很多事情。我建议你改用'DOMDocument'。它提供['loadXML()'](http://php.net/manual/en/domdocument.loadxml.php)和['saveXML()'](http://php.net/manual/en/) domdocument.savexml.php)将文档序列化为XML文本以及许多检查和修改其内容的方法。 – axiac

回答

0

据我所知,有没有干净内置的方式做什么,我需要任何的SimpleXMLElement或DOM文档做由于固有的设计libxml2。在XML处理之前,我最终用占位符替换了必要的字符(例如,将单引号替换为“{quot}”),然后将这些占位符与XML输出中适当的HTML实体进行交换。另外,如前面的评论中指出的那样,SimpleXMLElement不是普通的PHP类,这就是为什么我的重写尝试失败。

0

不使用简单的XML - 这是垃圾!

改为尝试DOMDocument()!

$dom = new DOMDocument(); 
$hello = $dom->createElement('hello'); 
$hello->setAttribute('such', 'wow'); 
$text = new DOMText('This & That'); 
$hello->appendChild($text); 
$dom->appendChild($hello); 
echo $dom->saveXML(); 

这将创建以下文件:

<?xml version="1.0"?> <hello such="wow">This &amp; That</hello>