<?php
$xmlDoc=new DOMDocument();
$xmlDoc->load('source.xml');
$properties = $xmlDoc->getElementsByTagName('property');
$first_property = $properties->item(0);
echo "$first_property->tagName\n";
$first_property_children = $first_property->childNodes;
echo $first_property_children->length;
/*
for ($j=4;$j<($cd->length);$j++) {
echo ("<div>" . $c->item($j)->attributes()->description . "</div>");
echo ("<div>" . $c->item($j)->childNodes["description"] . "</div>");
echo ("<div>" . $c->item($j)["description"] . "</div>");
}
*/
?>
--output:--
property
9
9??!! Wtf?! Here's what your xml file really looks like:
<property>\n #<==SEE THIS??
<name>a</name>\n #<==AND HERE??
<description>aaa</description>\n
<example value="b" description="bbb">b1</example>\n
<example value="c" description="ccc">c1</example> \n
</property>
When you hit Return
in a text file, an invisible newline character is entered into the file. Every one of the newlines is considered by xml to be enclosed in an invisible text node. Because there are 5 text nodes created by the 5 newlines inside the property
tag, as well as the 4 other visible nodes, there are a total of 9 children in the property
tag.
In your loop, so as to only land on the visible elements, you could start at childNodes[1]
(skipping the first newline text node), and then skip every other childNode:
for ($j=1; $j<($property_children->length); $j += 2) {
echo ("<div>" . $property_children->item($j)->nodeValue . "</div>\n");
//echo ("<div>" . $first_property_children->item($j)->nodeValue . "</div>");
//echo ("<div>" . $first_property_children->item($j)->childNodes["description"] . "</div>");
//echo ("<div>" . $first_property_children->item($j)["description"] . "</div>");
}
?>
--output:--
<div>a</div>
<div>aaa</div>
<div>b1</div>
<div>c1</div>
That gives you the text of all the visible tags.
Instead of looping, you can figure out the position of the description tag in the childNodes array. Here is where your description tag is located in the childNodes array:
+- from the spaces at the start of the next line
|
0 V 1 2 3
<property><text>\n </text><name>a</name><text>\n </text><description>aaa</description>....
So, you can write:
echo $property_children->item(3)->nodeValue; //nodeValue gives you the text
--output:--
aaa
But having to count nodes and take into account invisible text nodes created by whitespace inside a tag is too much of a hassle for us poor programmers, so there are other ways of obtaining a child node:
<?php
if ($property = simplexml_load_file('source.xml') )
{
//Grab all the child description tags in an Array:
echo $property->description[0] . "\n";
//Doing the same thing with xpath(which treats xml like a directory structure on your computer):
echo $property->xpath('./description')[0] . "\n";
}
?>
--output:--
aaa
aaa
See Basic SimpleXML usage in the php docs.
I want to return an attribute description.
An attribute? You mean the description attributes for all the example tags?
You can treat a tag like it is an array and use the attribute name as the subscript:
<?php
if ($property = simplexml_load_file('source.xml') )
{
$example_tags = $property->example;
foreach($example_tags as $example_tag) {
echo $example_tag['description'];
}
}
?>
--output:--
bbb
ccc
Here it is with xpath:
<?php
if ($property = simplexml_load_file('source.xml') )
{
$description_attrs = $property->xpath('./example/@description');
foreach($description_attrs as $description_attr) {
echo "$description_attr\n";
}
}
?>
--output:--
bbb
ccc