I'm not clear entirely what you're trying to do (you give no clear explanation of the desired output), but I will give you a few pointers:
- Ditch the conversion to array (the
json_decode(json_encode())
hack). All you're doing is throwing away the extra functionality that SimpleXML provides, and potentially throwing away part of the XML data. - One of the nice facilities of SimpleXML is that you can write
$xml->Product->Name
, and it means the first (0
th, if you like)Name
on the firstProduct
, and so does$xml->Product[0]->Name[0]
- regardless of whether there are actually multipleProduct
s andName
s. - You can also use
foreach ( $xml->Product as $product )
in much the way you'd expect - again, it works whether or not there are multipleProduct
nodes in that particular document. - If you don't mind learning a new syntax, XPath can be useful for hunting down nodes based on their value. In SimpleXML, you can start at any node (say, a particular
Product
) and use the->xpath()
method to get a plain array of "search results" starting at that node. - Your code also has some unnecessary duplication, in that the
elseif
does the same code as theif
, so you could just use an or (||
). (I'm not sure if this is just a result of anonymization.)
For comparison, here's a live demo of your code, with the XML snippets combined into one XML document.
Using SimpleXML itself, rather than just parsing to an array, you can simplify it down to this (Live Demo):
$xml = simplexml_load_string($xml_data);
foreach ( $xml->Product as $product )
{
foreach ( $product->Name as $name )
{
if ( $name->NameType == 1 || $name->NameType == 3 )
{
echo $name->NameText."\n";
break;
}
}
}
Using a simple XPath expression in place of the inner if
gives this version (Live Demo):
$xml = simplexml_load_string($xml_data);
foreach ( $xml->Product as $product )
{
foreach ( $product->xpath('Name[NameType=1 or NameType=3]') as $name )
{
echo $name->NameText."\n";
break;
}
}
Or you can go all the way and put all the logic into an XPath expression - note the [1]
on the end, which is the equivalent of the break;
in the inner loop, to stop multiple names being echo
d for one product (Live Demo):
$xml = simplexml_load_string($xml_data);
foreach ( $xml->xpath('Product/Name[NameType=1 or NameType=3][1]') as $name )
{
echo $name->NameText."\n";
}