I've got to parse and flatten an XML file that consists of a lot of single products. The XML is thoroughly documented and it's easy to parse the XML in PHP using SimpleXML. Please, see the code below how I'm creating an array from a single product. I then access all the required keys and store the data in an SQL database.
My problem now is, how to deal with varying child nodes. As you see in the provided XML snippets, there may be a single "Name" node, but sometimes there are two or even more of them. When there is more than one such node, I have to decide according to the "NameType" which "NameText" is the one to use. The same happens with the "Price" nodes.
<Product>
<Id>123</Id>
<Name>
<NameType>3</NameType>
<NameText>Hello World</NameText>
</Name>
<Price>
<Country>US</Country>
<Amount>9.90</Amount>
</Price>
</Product>
<Product>
<Id>124</Id>
<Name>
<NameType>1</NameType>
<NameText>Goodbye Cruel World</NameText>
</Name>
<Name>
<NameType>3</NameType>
<NameText>Goodbye Cruel World, I'm Leaving You Today</NameText>
</Name>
<Name>
<NameType>9</NameType>
<NameText>Goodbye</NameText>
</Name>
<Price>
<Country>CAN</Country>
<Amount>27.90</Amount>
</Price>
<Price>
<Country>US</Country>
<Amount>19.90</Amount>
</Price>
</Product>
Here's my code to deal with this problem: I transform the XML to an associative array and then use a lot of if-magic to get the data I need. The provided code prints out "Hello World" for the first product example and "Goodbye Cruel World" for the second.
$xml = simplexml_load_string($product);
$json = json_encode($xml);
$arr = json_decode($json, True);
// $arr['Name']['NameText'] contains the single NameText for this product in example one
// $arr['Name'][0]['NameText'] contains the first of three NameTexts in example two
if( array_key_exists(0, $arr['Name']) ) {
foreach( $arr['Name'] as $n) {
if( $n['NameType'] == 1 ) {
echo $n['NameText']."\n";
break;
} elseif ( $n['NameType'] == 3 ) {
echo $n['NameText']."\n";
break;
}
}
} else {
echo $arr['Name']['NameText']."\n";
}
While this code is working, I'm not very glad with the case-by-case analysis for all of the nodes that may occur multiple times. And I even have to depend on the "correct" order of the child nodes, assuming that NameType "1" always happens to come before NameType "3". So I'm inclined to hope that there is a smarter solution out there.
The question XML with varying amount of child nodes for each parent node seems to be similar, but it doesn't really address the part with varying amount of child nodes and the task to select a special child node.