PHP SimpleXML中的XML到JSON转换

时间:2014-12-24 09:04:28

标签: php xml json

            $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字符串。我使用了以下代码。

           $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"
            }
         }
      ]
   }

但我不想要&#34; @属性&#34;。我想要输出如下:

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

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您不希望在JSON中编码“@attributes”字段,但这是PHP JSON序列化SimpleXMLElement的标准方法。

正如您所说,您想要更改它,您需要更改PHP JSON序列化对象的方式。这可以通过自己实现JsonSerializable SimpleXMLElement 来实现,然后根据需要提供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;
    }
}

E.g。将属性用作所有子元素的字段。

然后您可以轻松地将其集成,例如而不是

$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的规则感兴趣。
  • 如果某个属性与子元素同名,则子元素将覆盖该属性。
  • 如果子元素跟随另一个具有相同名称的子元素,则它将被覆盖。

最后两点只是为了简化示例代码。在我的一系列博客文章中给出了与 SimpleXMLElement 的标准PHP JSON序列化一致的方法。

第三篇文章中提供了完整此过程和示例 JsonSerialize 实现的基础知识:SimpleXML and JSON Encode in PHP – Part III and End

另一个相关问题是:

答案 1 :(得分:0)

$fileContents= file_get_contents("https://www.feedforall.com/sample.xml");
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
$array = json_decode($json,TRUE); // convert the JSON-encoded string to a PHP variable
return $array;

更好的例子: