I'm having some trouble with reading XML files in PHP. I'm not very skilled in PHP, so I use this code snippet: Article.
This is the XML file I'm trying to read: http://pastebin.com/2dtMp5VH
<?xml version="1.0" encoding="UTF-8"?>
<contentdata>
<Games>
<numberof>2</numberof>
<nameof>
<n1>Game1</n1>
<n2>Game2</n2>
</nameof>
</Games>
<Software>
<开发者_开发问答numberof>1</numberof>
<nameof>
<n1>Software1</n1>
</nameof>
</Software>
</contentdata>
This is my PHP script, based on the article I gave: http://pastebin.com/d29ejxSJ
$objDOM = new DOMDocument();
$objDOM->load("content.xml");
$note = $objDOM->getElementsByTagName("Games");
foreach( $note as $value )
{
$numberof = $value->getElementsByTagName("numberof");
$numberof_ = $numberof->item(0)->nodeValue;
echo($numberof_." games found!<br />");
$numberof = (integer)$numberof_;
$nameof = $value->getElementsByTagName("nameof");
$i = 1;
foreach($nameof as $value2)
{
$n = (string)$i;
$nameof_[$i] = $value2->getElementsByTagName("n".$n);
$nameof_[$i] = $nameof_[$i]->item(0)->nodeValue;
echo(((string)$i).": ".$nameof_[$i]."<br />");
$i++;
}
}
The output should be this:
2 games found! 1: Game1 2: Game2However, for some reason it only outputs the following:
2 games found! 1: Game1What is wrong with my code? How to solve this?
Like @chris sayd, I think you make the second foreach
on the bad node.
Your second foreach
target : nameof
and not his content (n1, n2, ...)
With Simple XML:
$Games = $value->getElementsByTagName("nameof")->children();
foreach($Games as $value2)
{
// Your code to parse <nX>
}
We need to see your XML, to really help with this BUT...
I think you might be confusing elements and attributes. In brief, XML is composed like this
<tagname attr1=5 attr2='arf'> BODY HERE </tagname>
In your case, I don't believe numberof
and nameof
are elements at all. They seem to be attributes belonging to Games
elements.
Use echoes or var_dump
to show the contents of variables like $notes
and $numberof
I think you'll find they don't contain what you're expecting.
In $value you are keeping a reference of the Games
node which containes just one single nameof
node. Then later you make
foreach($nameof as $value2)
which will be executed exactly one time because there is only one nameof node in it. Your $i will stay 1 so only game one will be printed out.
What you need to do is selecting all the "nX" nodes and iterating through them but not through the nameof nodes because theres only one of it. Alternatively you can change the for loop so that you iterate exactly as much as is written in numberof
.
It seems like your problem is iterating through all the child elements in the <nameof>
tag.
try the following:
foreach($nameof as $node){
foreach($node->childNodes as $child) {
echo '<br/>Node Name: '.$child->nodeName.' Node Value: '.$child->nodeValue.'<br/>';
}
}
instead of your last foreach
statement and observe the output
You second foreach
is wrong as it only evaluate after the nameof
entries in Games
which is currently one entry.
You will need to use your nameof_
to iterate in your case:
$objDOM = new DOMDocument();
$objDOM->load("content.xml");
$note = $objDOM->getElementsByTagName("Games");
foreach( $note as $value )
{
$numberof = $value->getElementsByTagName("numberof");
$numberof_ = $numberof->item(0)->nodeValue;
echo($numberof_." games found!<br />\n");
$numberof = (integer)$numberof_;
$nameof = $value->getElementsByTagName("nameof");
for ($i = 1; $i <= $numberof_; $i++)
{
$n = (string)$i;
$nameof_[$i] = $nameof->item(0)->getElementsByTagName("n".$n);
$nameof_[$i] = $nameof_[$i]->item(0)->nodeValue;
echo(((string)$i).": ".$nameof_[$i]."<br />\n");
}
}
As a advisory take a closer look at your data definition -like @jon_darkstar suggested as well- it does not look very XMLish (eg easy automatic parseble).
If you for example use this format, parsing will be more easy:
<?xml version="1.0" encoding="utf-8"?>
<contentdata>
<Games>
<item name="Game1" />
<item name="Game2" />
</Games>
<Software>
<item name="Software1" />
</Software>
</contentdata>
Which you can than parse using
$objDOM = new DOMDocument();
$objDOM->load("content.xml");
$gamesElements = $objDOM->getElementsByTagName("Games");
foreach ($gamesElements as $gamesElement)
{
$itemElements = $gamesElement->getElementsByTagName("item");
echo ($itemElements->length . " games found!<br />\n");
$i = 1;
foreach ($itemElements as $itemElement) {
$name = $itemElement->attributes->getNamedItem('name')->nodeValue;
echo("$i: $name<br />\n");
$i++;
}
}
Take a look over SimpleXML function: simplexml_load_string
.
精彩评论