Reputation: 113
<tle-type name="Channel" tag="47" mt="true">
<tle-field name="ChannelId" tag="1" type="String" minOccurs="1" maxOccurs="1">
Description 1.
</tle-field>
<tle-field name="resultCode" tag="2" enum="true" type="ChannelResult" minOccurs="1" maxOccurs="1">
Description 2.
</tle-field>
<tle-field name="jid" tag="3" type="String" minOccurs="0" maxOccurs="1">
Description 3.
</tle-field>
<tle-field name="thing" tag="4" type="String" minOccurs="0" maxOccurs="1">
Description 5.
</tle-field>
</tle-type>
Above is a section of XML that I am dealing with. The 'tag' attribute under 'tle-type' is the unique identifier and then in it's children 'tle-field' will be another 'tag' attribute. I'm essentially looking for a way to identify the first 'tag' 'tle-type', then create a $attribute = "value" out of 'tle-field', with the description in $desc.
While I can pull out the 'tle-type' attribute with tag="x", I cannot seem to pull the child attributes out where the tag = 'y'. I can just print all the attributes.
foreach ($xml->getElementsByTagName('tle-type') as $tag) {
if($tag->getAttribute('tag') === '47') {
foreach ($tag->childNodes as $child ) {
foreach ($child->attributes as $t ) {
echo "<BR>".$t->nodeName." = ".$t->nodeValue;
}
}
}
}
With the above, I end up with Warning: Invalid argument supplied for foreach() in file.php on line 4:
foreach ($child->attributes as $t)
Yet the attribute names and values show up, minus the description, of course. I hope I've explained this alright...
Any assistance would be appreciated!
Upvotes: 1
Views: 1272
Reputation: 19482
The childnodes, are not only elements, but text nodes, too. So you get the whitespace text nodes. They have no attributes and an error is thrown.
I modified your source to show the classes: https://eval.in/112204
$dom = new DOMDocument();
$dom->loadXml($xml);
foreach ($dom->getElementsByTagName('tle-type') as $tag) {
if($tag->getAttribute('tag') === '47') {
foreach ($tag->childNodes as $child) {
var_dump(get_class($child));
}
}
}
So you would have to check if the child is an instance of DOMElement
. But here is an easier way. Create an Xpath object and use expressions:
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$result = [];
foreach ($xpath->evaluate('//tle-type[@tag = "47"]/tle-field') as $field) {
$result[$field->getAttribute('name')] = $field->nodeValue;
}
var_dump($result);
Output: https://eval.in/112222
array(4) {
["ChannelId"]=>
string(22) "
Description 1.
"
["resultCode"]=>
string(27) "
Description 2.
"
["jid"]=>
string(22) "
Description 3.
"
["thing"]=>
string(22) "
Description 5.
"
}
Upvotes: 3