简体   繁体   中英

Converting XML to JSON using xml_parse_into_struct

I'm working on a server that does not have PHP's simpleXML available and need to convert an XML string to JSON so I'm using xml_parse_into_struct() to get the job done. I'm then attempting to combine the two arrays it produces with array_combine() and then use json_encode() to return a JSON representation of the XML string. The problem I'm having is that the two arrays xml_parse_into_struct() is creating are not of equal lengths so array_combine() is throwing an error. I believe this could be caused by the XML string having a bunch of elements with the same name. How can I convert this xml string to JSON and retain all of the elements and their attributes without simpleXML?

code:

$string =
'<?xml version="1.0" encoding="UTF-8"?>
<session-data xmlns="http://oracle.com/determinations/engine/sessiondata/10.2">
   <entity id="global">
      <instance id="global">
         <attribute id="employer" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="legal" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="foodtype" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="app" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="org" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="tel" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="jfu" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="trans" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="serv" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="cit" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="street" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="zip" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="ddt" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="prov" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="prov2" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="teh" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="dis" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="num" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="ssn" type="text" inferred="false">
            <text-val>social</text-val>
         </attribute>
         <attribute id="eop" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="inst" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="cig" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="nips" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="pay" type="number" inferred="true">
            <number-val>200.0</number-val>
         </attribute>
         <attribute id="data" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="ent" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="ent2" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="person" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="activity" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="tob" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="start" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="tate" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="procs" type="text" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="officers" type="text" inferred="false">
            <text-val>3 or more Officers</text-val>
         </attribute>
         <attribute id="time" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="year" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="box" type="boolean" inferred="false">
            <unknown-val />
         </attribute>
         <attribute id="digi" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="store" type="boolean" inferred="false">
            <boolean-val>true</boolean-val>
         </attribute>
         <attribute id="rent" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="tain" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="goo" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="building" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="guard" type="boolean" inferred="false">
            <boolean-val>false</boolean-val>
         </attribute>
         <attribute id="hard" type="boolean" inferred="false">
            <boolean-val>true</boolean-val>
         </attribute>
            <unknown-val />
         </attribute>
         <entity id="regulated" complete="false" inferred="false" />
      </instance>
   </entity>
</session-data>';


$p = xml_parser_create();
xml_parse_into_struct($p, $string, $vals, $index);
xml_parser_free($p);



$jsonArray = array();
foreach (array_combine( $index, $vals ) as $name => $value) {
    $jsonArray[] = array('name' => $name, 'value' => $value);
}

echo "Encoded JSON:<br>";
print_r($json = json_encode($jsonArray));

Consider manipulating the $vals array further to account for nested tree structure (siblings, children, etc.). As is, xml_parse_struct() returns objects all in same level with only attributes as nested array. Below uses this raw output array and by design of xml tree, defines other arrays with corresponding values for nested structure.

PHP Script

// EXTRACT XML CONTENT
$p = xml_parser_create();
xml_parse_into_struct($p, $string, $vals, $index);
xml_parser_free($p);

// INITIALIZE PARENT/CHILD ARRAYS
$session = []; $entity = []; $instance = [];
$attribute = []; $boolean = []; $unknown = [];

// POPULATE "OPEN" ELEMENTS WITH ATTRIBUTES
foreach($vals as $v){    
    if($v['tag'] == "SESSION-DATA" and $v['type']=="open"){
        $session['session-data'] = $v['attributes'];
    }
    if($v['tag'] == "ENTITY" and $v['type']=="open"){
        $entity = $v['attributes'];
    }
    if($v['tag'] == "INSTANCE" and $v['type']=="open"){
        $instance = $v['attributes'];
    }    
}

// NEST BOOLEAN-VAL/UNKNOWN-VAL UNDER ATTRIBUTE
$j=0;
for($i=0; $i<sizeof($vals); $i++){
    if($vals[$i]['tag'] == "ATTRIBUTE" and $vals[$i]['type']=="open"){
        $attribute[$j] = $vals[$i]['attributes'];
        $j++;
    }
    if($vals[$i]['tag'] == "BOOLEAN-VAL" and $vals[$i]['type']=="complete"){
        $boolean['value'] = $vals[$i]['value'];
        $attribute[$j-1]['BOOLEAN-VAL'] = $boolean;
    }    
    if($vals[$i]['tag'] == "UNKNOWN-VAL" and $vals[$i]['type']=="complete"){
        $unknown['value'] = $vals[$i]['type']=="complete";
        $attribute[$j-1]['UNKNOWN-VAL'] = $unknown;
    }
}

// ADD CHILD ARRAYS TO PARENTS
$instance['attributes'] = $attribute;
$entity['instance'] = $instance;
$session['session-data']['entity'] = $entity;

echo "Encoded JSON:<br>";
print_r($json = json_encode($session));

// PRETTY PRINT OUTPUT TO FILE
$json = json_encode($session, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
file_put_contents("Output.json", $json);

Pretty Print JSON Output (according to online sources , is a valid json)

{
    "session-data": {
        "XMLNS": "http://oracle.com/determinations/engine/sessiondata/10.2",
        "entity": {
            "ID": "global",
            "instance": {
                "ID": "global",
                "attributes": [
                    {
                        "ID": "employer",
                        "TYPE": "text",
                        "INFERRED": "false",
                        "UNKNOWN-VAL": {
                            "value": true
                        }
                    },
                    {
                        "ID": "legal",
                        "TYPE": "text",
                        "INFERRED": "false",
                        "UNKNOWN-VAL": {
                            "value": true
                        }
                    },
                    {
                        "ID": "foodtype",
                        "TYPE": "text",
                        "INFERRED": "false",
                        "UNKNOWN-VAL": {
                            "value": true
                        }
                    },
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM