Now for me to blog everything I didn't get to blog while I wasn't blogging. 
While trying to get my XML-RPC client to work, the most difficult problem I had was transforming the output of xml_parse_into_struct() into something useful to me. I kept trying to do it by the seat of my pants, and it wasn't working. I got really close, but couldn't get it how I wanted.
Just to show you an example of what I wanted to do... say you had an XML document like so (using lists just for indentation):
- <?xml version="1.0" ?>
- <methodResponse>
- <fault>
- <value>
- <struct>
- <member>
- <name>faultCode</name>
- <value>
- </value>
- </member>
- <member>
- <name>faultString</name>
- <value>You bastards!</value>
- </member>
- </struct>
- </value>
- </fault>
- </methodResponse>
I'd want to be able to transform it seamlessly back and forth between this data structure (in PHP):
<?php
$array["methodResponse"]["fault"]["value"]["struct"]["member"][0]["name"] = "faultCode";
$array["methodResponse"]["fault"]["value"]["struct"]["member"][0]["value"]["int"] = "1";
$array["methodResponse"]["fault"]["value"]["struct"]["member"][1]["name"] = "faultString";
$array["methodResponse"]["fault"]["value"]["struct"]["member"][1]["value"] = "You bastards!";
?>
I actually lied down on the floor with a printout of the data structure that xml_parse_into_struct() gives you and wrote down, in low-level pseudocode, what had to happen at each node. Then I was able to transfer that to code. There was one case I had to account for that didn't come up in the data I was working with at the time, but that was easy to add.
Here's the code:
<?php
function XML_struct_transform($values){
$root = array();
$current_parent = &$root;
for($n = 0; $n<count($values); $n++){
$value = $values[$n];
$level = $value["level"];
$type = $value["type"];
$tag = $value["tag"];
$val = $value["value"];
if($type == "open"){
if($level > 1 and isset($current_level_parent[$level-2][$tag])){ #if you've already seen one of these tags
$current_parent = &$current_level_parent[$level-2];
if(!isset($current_parent[$tag][0])){ #if you've only seen *one* of these tags
$temp = &$current_parent[$tag];
unset($current_parent[$tag]);
$current_parent[$tag][0] = &$temp;
$current_parent[$tag][1] = array();
$current_parent = &$current_parent[$tag][1];
}else{ #if you've seen more than one of these tags
$count = count($current_parent[$tag]);
$current_parent[$tag][$count] = array();
$current_parent = &$current_parent[$tag][$count];
}
}else{
$current_parent[$tag] = array();
$current_parent = &$current_parent[$tag];
}
$current_level_parent[$level-1] = &$current_parent;
}elseif($type == "complete"){
if($level > 1){
$current_level_parent[$level-2][$tag] = $val;
}else{
$root = array($tag => $val);
}
}
}
return $root;
}
?>
Feel free to post a comment below. Please see my comment policy.
Formatting Rules (No HTML):