2014-12-24 59 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