0

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));
4
  • Does server have DomDocument() available to query XML into array? Commented Feb 22, 2016 at 19:12
  • Thanks for the reply @Parfait - DOMDocument() does not appear to be available. Commented Feb 22, 2016 at 19:25
  • Is this a private, local server? If so, ask IT dept or you yourself install those extensions which interestingly are enabled by default. And most commercial webhosts would have these extensions enabled. You do yourself a disfavor developing in PHP without core xml classes. Commented Feb 22, 2016 at 21:07
  • @Parfait, This site is hosted by Oracle in their Service Cloud CRM. For whatever reason, they've disabled a handful of really useful functions and make it extremely difficult to have them enable these. What I'm trying to accomplish here could be done with simpleXML in about 3 lines of code, so I agree with you on the disfavor of not having the core classes. Thanks! Commented Feb 24, 2016 at 13:47

1 Answer 1

1

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
                        }
                    },
...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.