XML to JSON conversion in PHP SimpleXML

前端 未结 2 1054
面向向阳花
面向向阳花 2021-01-24 01:11
            $data = \"
            Y
            
            

        
相关标签:
2条回答
  • 2021-01-24 01:59
    $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;
    

    I'ts Better example:

    0 讨论(0)
  • 2021-01-24 02:03

    You don't want to have the "@attributes" field encoded in the JSON, however this is the standard way how PHP JSON serializes a SimpleXMLElement.

    As you say you want to change that, you need to change the way how PHP JSON serializes the object. This is possible by implementing JsonSerializable with a SimpleXMLElement on your own and then provide the JSON serialization as you wish:

    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. by using the attributes as fields like all the child elements.

    You can then just integrate it easily, e.g. instead of

    $xml = simplexml_load_string($result);
    

    you can use

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

    or just

    $xml = new JsonSerializer($result);
    

    and the rest of your function works the same but just with your wishes serialization.

    Example:

    $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;
    

    Output:

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

    The serialization function for the example above is:

    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;
    }
    

    Some notes here:

    • In the serialization you have to take care of the type of element your own. The differentiation is done on top for the single elements with no children. If you need attribute handling on these, you need to add it.
    • The trim($this) perhaps already spares you the issue you try to catch with $result = str_replace(array("\n", "\r", "\t"), '', $data);. SimpleXMLElement in any case would JSON serialize "\r" characters (SimpleXMLElement makes use of "\n" for breaks). Additionally you might be interested in the rules of whitespace normalization in XML.
    • In case an attribute has the same name as a child element, it will be overwritten by the child element.
    • In case a child element that follows another child element with the same name, it will be overwritten.

    The two last points are just to keep the example code simple. A way that is aligned to standard PHP JSON serialization of a SimpleXMLElement is given in a series of blog posts of mine.

    Basics of exactly this procedure and an exemplary JsonSerialize implementation is available in the third post: SimpleXML and JSON Encode in PHP – Part III and End.

    Another related question is:

    • PHP convert XML to JSON group when there is one child
    0 讨论(0)
提交回复
热议问题