doujiazong0322 2016-02-22 16:12
浏览 67
已采纳

使用xml_parse_into_struct将XML转换为JSON

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));
  • 写回答

1条回答 默认 最新

  • duanpin2034 2016-02-25 04:36
    关注

    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
                            }
                        },
    ...
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?