php simpleXMLElement to array: null value

后端 未结 3 1781
南方客
南方客 2021-02-14 13:49

I\'ve got following XML:


    123
    
    ACTIVE



        
相关标签:
3条回答
  • 2021-02-14 14:14

    I cannot add a comment, but I think this will work for you, it should be faster then a regex or a loop:

    //after you json_encode, before you decode
    $str = str_replace(':[]',':null',json_encode($array));
    

    An empty array in JSON is represented by "[]". Sometimes the arrays are parsed as objects, in that case (or as a fallback) you can replace ":{}" too.

    0 讨论(0)
  • 2021-02-14 14:25

    Check performance str_replace vs recursive loop

    • Iterations: 100000
    • XML length: 4114 bytes
    • Init script time: ~1.2264486691986E-6 seconds
    • JSON encode/decode time: ~9.8956169957496E-5 seconds
    • str_replace average time: 0.00010692856433176 seconds
    • recursive loop average time: 0.00011844366600813 seconds

    The str_replace quickly on ~0.00001 seconds. The difference will be noticeable in many calls

    0 讨论(0)
  • 2021-02-14 14:37

    An empty SimpleXMLElement object will be casted to an empty array. You can change this by by extending from SimpleXMLElement and implementing the JsonSerializable interface and casting an it to null.

    /**
     * Class JsonXMLElement
     */
    class JsonXMLElement extends SimpleXMLElement implements JsonSerializable
    {
    
        /**
         * Specify data which should be serialized to JSON
         *
         * @return mixed data which can be serialized by json_encode.
         */
        public function jsonSerialize()
        {
            $array = array();
    
            // json encode attributes if any.
            if ($attributes = $this->attributes()) {
                $array['@attributes'] = iterator_to_array($attributes);
            }
    
            // json encode child elements if any. group on duplicate names as an array.
            foreach ($this as $name => $element) {
                if (isset($array[$name])) {
                    if (!is_array($array[$name])) {
                        $array[$name] = [$array[$name]];
                    }
                    $array[$name][] = $element;
                } else {
                    $array[$name] = $element;
                }
            }
    
            // json encode non-whitespace element simplexml text values.
            $text = trim($this);
            if (strlen($text)) {
                if ($array) {
                    $array['@text'] = $text;
                } else {
                    $array = $text;
                }
            }
    
            // return empty elements as NULL (self-closing or empty tags)
            if (!$array) {
                $array = NULL;
            }
    
            return $array;
        }
    }
    

    Then tell simplexml_load_string to return an object of JsonXMLElement class

    $xml = <<<XML
    <account>
       <id>123</id>
       <email></email>
       <status>ACTIVE</status>
    </account>
    XML;
    
    $obj = simplexml_load_string($xml, 'JsonXMLElement');
    
    // print_r($obj);
    
    print json_encode($obj, true);
    
    /*
     * Output...
    {
       "id": 123,
       "email": null,
       "status": "ACTIVE"
    }
    */
    

    Credit: hakre

    0 讨论(0)
提交回复
热议问题