Reputation: 6217
I'm currently doing this to build an array called $tables
, but wondering if there is an easier way to do this?
$tables = array();
$abbr = $states_xml->xpath('//StateAbbr');
$names = $states_xml->xpath('//StateName');
// State Abbreviations...
while(list($key,$table) = each($abbr)) {
$tables[$key]['Abbr'] = (string) trim($table);
}
// State Names...
while(list($key,$name) = each($names)) {
$tables[$key]['Name'] = (string) trim($name);
}
Is it possible to call StateAbbr
and StateName
elements in 1 go and have them be outputted in an array in the same format as $tables
is?
So, tables array will look something like this:
array(57) {
[0]=>
array(2) {
["Abbr"]=>
string(2) "AL"
["Name"]=>
string(7) "Alabama"
}
[1]=>
array(2) {
["Abbr"]=>
string(2) "AK"
["Name"]=>
string(6) "Alaska"
}
[2]=>
array(2) {
["Abbr"]=>
string(2) "AS"
["Name"]=>
string(14) "American Samoa"
}
... and so on...
Basically, the $states_xml
looks like this:
<diffgr:diffgram
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet
xmlns="">
<Table diffgr:id="Table1" msdata:rowOrder="0">
<StateAbbr>AL </StateAbbr>
<StateName>Alabama</StateName>
</Table>
<Table diffgr:id="Table2" msdata:rowOrder="1">
<StateAbbr>AK </StateAbbr>
<StateName>Alaska</StateName>
</Table>
<Table diffgr:id="Table3" msdata:rowOrder="2">
<StateAbbr>AS </StateAbbr>
<StateName>American Samoa</StateName>
</Table>
<Table diffgr:id="Table4" msdata:rowOrder="3">
<StateAbbr>AP </StateAbbr>
<StateName>AP</StateName>
</Table>
...
</NewDataSet>
</diffgr:diffgram>
I am using $states_xml = simplexml_load_string(THE STRING ABOVE);
to load up the xml into $states_xml
.
Anyway to grab all StateAbbr
and StateName
from all Table
elements in here to be outputted in an array, in one go?? Seems possible to me, but not sure how to approach this other than the way I'm currently doing it.
Upvotes: 2
Views: 1660
Reputation: 19482
You should iterate their parent element node. The expressions are relative to the node the SimpleXMLElement represents, but that is not needed in your case:
$diffgram = new SimpleXMLElement($xml);
$result = [];
foreach($diffgram->xpath('.//Table') as $table) {
$result[] = [
'Abbr' => trim($table->StateAbbr),
'Name' => trim($table->StateName)
];
}
var_dump($result);
Output:
array(4) {
[0]=>
array(2) {
["Abbr"]=>
string(2) "AL"
["Name"]=>
string(7) "Alabama"
}
[1]=>
array(2) {
["Abbr"]=>
string(2) "AK"
["Name"]=>
string(6) "Alaska"
}
[2]=>
array(2) {
["Abbr"]=>
string(2) "AS"
["Name"]=>
string(14) "American Samoa"
}
[3]=>
array(2) {
["Abbr"]=>
string(2) "AP"
["Name"]=>
string(2) "AP"
}
}
In DOM it looks nearly the same, but here you need Xpath expressions for the details.
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$result = [];
foreach($xpath->evaluate('.//Table') as $table) {
$result[] = [
'Abbr' => $xpath->evaluate('normalize-space(StateAbbr)', $table),
'Name' => $xpath->evaluate('normalize-space(StateName)', $table)
];
}
var_dump($result);
Upvotes: 2
Reputation: 111491
Yes, this single XPath,
//*[self::StateAbbr or self::StateName]
will return all StateAbbr
and StateName
elements in an XML document.
Upvotes: 0
Reputation: 8748
please try this using array_merge_recursive :
$abbr = $states_xml->xpath('//StateAbbr');
$names = $states_xml->xpath('//StateName');
$tables = array_merge_recursive($abbr, $names);
display:
print_r($tables);
Upvotes: 0