2014-12-24 98 views
1
  $data = "<QRYRESULT> 
      <ISSUCCESS>Y</ISSUCCESS> 
      <EBLCUSTOMER ACCOUNTNO='11111'> 
      <CUSTACCTNO>121212</CUSTACCTNO> 
      <ACCTSTATUS>active</ACCTSTATUS> 
      <CCYDESC>BDT</CCYDESC> 
      <BALANCE>9999</BALANCE> 
      <AVAILABLEBALANCE>99</AVAILABLEBALANCE> 
      <CUSTOMERNAME>cus_name</CUSTOMERNAME> 
      <AMOUNTONHOLD>1000</AMOUNTONHOLD> 
      <ODLIMIT>99</ODLIMIT> 
      </EBLCUSTOMER> 
      </QRYRESULT>"; 

這是我想要轉換的XML字符串。我已經使用了下面的代碼。XML到JSON轉換在PHP SimpleXML

  $result = str_replace(array("\n", "\r", "\t"), '', $data); 
      $xml = simplexml_load_string($result); 
      $object = new stdclass(); 
      $object->webservice[] = $xml; 
      $result = json_encode($object); 
      header('content-Type: application/json'); 
      echo $result; 

我得到以下json數據。

{ 
    "webservice": [ 
     { 
     "ISSUCCESS": "Y", 
     "CUSTSUMMARY": { 
      "@attributes": { 
       "ACCOUNT": "11111" 
      }, 
      "IDACCOUNT": "1010101", 
      "CODACCTCURR": "BDT", 
      "NUMBALANCE": "99999", 
      "ACCTDESC": "22222", 
      "PRDNAME": "name" 
      } 
     } 
     ] 
    } 

但我不想「@attributes」。我想要輸出如下:

{ 
    "QRYRESULT": { 
    "ISSUCCESS": "Y", 
    "EBLCUSTOMER": { 
    "-ACCOUNTNO": "11111", 
    "CUSTACCTNO": "121212", 
    "ACCTSTATUS": "active", 
    "CCYDESC": "BDT", 
    "BALANCE": "9999", 
    "AVAILABLEBALANCE": "99", 
    "CUSTOMERNAME": "cus_name", 
    "AMOUNTONHOLD": "1000", 
    "ODLIMIT": "99" 
    } 
    } 
    } 

我該怎麼做?

回答

2

您不希望在JSON中編碼「@attributes」字段,但這是PHP JSON如何序列化SimpleXMLElement的標準方式。如你所說你想改變它,你需要改變PHP JSON如何序列化對象的方式。這是可能通過與的SimpleXMLElement對自己實施JsonSerializable,然後提供JSON序列如你所願:

class JsonSerializer extends SimpleXmlElement implements JsonSerializable 
{ 
    /** 
    * SimpleXMLElement JSON serialization 
    * 
    * @return null|string 
    * 
    * @link http://php.net/JsonSerializable.jsonSerialize 
    * @see JsonSerializable::jsonSerialize 
    */ 
    function jsonSerialize() 
    { 
     // jishan's SimpleXMLElement JSON serialization ... 

     return $serialized; 
    } 
} 

例如通過使用屬性作爲像所有子元素一樣的字段。

然後你可以很容易地整合它,例如,而不是

$xml = simplexml_load_string($result); 

可以使用

$xml = simplexml_load_string($result, 'JsonSerializer'); 

或只是

$xml = new JsonSerializer($result); 

和你的函數的其餘部分的工作方式相同,但只是與你的願望系列化。

實施例:

$result = str_replace(array("\n", "\r", "\t"), '', $data); 
$xml = new JsonSerializer($result); 
$object = new stdclass(); 
$object->webservice[] = $xml; 
$result = json_encode($object, JSON_PRETTY_PRINT); 
header('content-Type: application/json'); 
echo $result; 

輸出:

{ 
    "webservice": [ 
     { 
      "EBLCUSTOMER": { 
       "ACCOUNTNO": "11111", 
       "CUSTACCTNO": "121212", 
       "ACCTSTATUS": "active", 
       "CCYDESC": "BDT", 
       "BALANCE": "9999", 
       "AVAILABLEBALANCE": "99", 
       "CUSTOMERNAME": "cus_name", 
       "AMOUNTONHOLD": "1000", 
       "ODLIMIT": "99" 
      } 
     } 
    ] 
} 

對於上面的例子中的串行化函數是:

function jsonSerialize() 
{ 
    // text node (or mixed node represented as text or self closing tag) 
    if (!count($this)) { 
     return $this[0] == $this 
      ? trim($this) : null ; 
    } 

    // process all child elements and their attributes 
    foreach ($this as $tag => $element) { 
     // attributes first 
     foreach ($element->attributes() as $name => $value) { 
      $array[$tag][$name] = $value; 
     } 
     // child elements second 
     foreach($element as $name => $value) { 
      $array[$tag][$name] = $value; 
     } 
    } 

    return $array; 
} 

一些這裏說明:

  • 在序列化中,您必須關心您自己的元素類型。對於沒有孩子的單個元素來說,分化是在頂部完成的。如果你需要對這些屬性進行處理,你需要添加它。
  • trim($this)或許已經爲您解決了您嘗試使用$result = str_replace(array("\n", "\r", "\t"), '', $data);來解決的問題。 SimpleXMLElement在任何情況下都會將JSON序列化爲「\r」字符(SimpleXMLElement利用「\n」作爲休息時間)。此外,您可能對whitespace normalization in XML的規則感興趣。
  • 如果屬性與子元素具有相同的名稱,則它將被子元素覆蓋。
  • 如果一個子元素跟在另一個具有相同名稱的子元素之後,它將被覆蓋。

最後兩點只是保持示例代碼的簡單。在我的一系列博客文章中給出了一種與標準PHP JSON序列化相對應的方法,其中包括SimpleXMLElement

完全按照此過程的基本知識和示例JsonSerialize實現在第三篇文章中提供:SimpleXML and JSON Encode in PHP – Part III and End

另一個相關的問題是:

+0

,因爲我用笨框架我所做的是在我的控制器類寫的jsonSerialize()函數,並把它稱爲從功能中,我我正在使用XML進行json轉換,如$ xml = $ this-> jsonSerialize();然後我的代碼的其餘部分,但我得到以下錯誤:'致命錯誤:調用未定義的方法CI_Benchmark :: attributes()@hakre – Ishrak

+0

試着讓它在沒有Codeigniter的情況下運行,以便您可以檢查它是否工作。類名** CI_Benchmark **可能表明某些內容與Codeigniter混合並在此時引起誤解。 – hakre