2017-05-26 102 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>