xpath inside a foreach loop repeating same result
I Use the following code to parse an XML file, with no problem:
foreach ($xml->product as $products) {
$title = $products->name; etc etc
However, due to structure of the XML I have to use xpath on one of the nodes I need to ensure it returns the correct data
$actors = $xml->xpath("//property[name[. ='Actors']]/value");
$actor = $actors[0];
This works great but it always returns the first record of the XML file where I need it to keep up with the loop, if that makes sense.
I tried the following but the same thing happens:
$actors = $products->xpath("//property[name[. ='Actors']]/value");
Here is the xml in question, however my example above uses a node called name which has data Actors, swap that for Format and you have the same idea as there is a node below which is
<name>Format</name>
<properties>
<group>
<name>Product</name>
<property>
&开发者_JAVA技巧lt;id>48546006</id>
<name>Product name</name>
<value>JOLLY PHONICS (JOLLY PHONICS S.)</value>
</property>
</group>
<group>
<name>Product properties</name>
<property>
<id>43560296</id>
<name>Product Title</name>
<value>JOLLY PHONICS (JOLLY PHONICS S.)</value>
</property>
<property>
<id>43560292</id>
<name>Format</name>
<value>DVD</value>
</property>
</group>
</properties>
and here is the full foreach loop i'm using (I've omitted some of it as you don't need to read multiple things that all work correctly as you'll see:
foreach ($xml->product as $products) { // AA
$title = $products->name;
$PRid = $products->id;
$actors = $xml->xpath("//property[./name[.='Actors']]/value[next()]"); // this ok but repeats
$actors = $actors[0];
$genre = $xml->xpath("//property[name[. ='Genre']]/value");
$genre = $genre[0];
$prodcat = $products->{'category'};
$addline = mysql_query("
insert into dbname(
blah blah
)
VALUES (
blah blah
) ON DUPLICATE KEY UPDATE lowprice='$lowprice', highprice='$highprice'",$db);
if(!$addline) { echo "cannot add to table here".mysql_error(); exit; } // debug
foreach ($xml->product->retailer as $retailer) { // BB
this is another foreach loop but works perfectly
} // close BB
} // close AA
So, the problem is - I have nodes within the XML file that I need to extract which are always within the node called property, but, I can't simply use e.g. name[2] as they are sometimes in different places - therefore it is suggested I use xpath to get the data from the specific node I need as it's more precise - and the problem with that is that it works ok but for some reason will not simply get the data from the current node, however I try ./ or .//, it always returns the data from the first node.
Any ideas?
As I suspected (before you posted your PHP code). You do not use relative paths in a loop body. Of course this always produces the same (i.e. the absolute) result.
You must refer to $product
(not $xml
) with your XPath and use a relative path from there, like this:
foreach ($xml->product as $product) { // AA
$title = $product->name;
$PRid = $product->id;
$actors = $product->xpath(".//property[name='Actors']/value");
$genre = $product->xpath(".//property[name='Genre']/value");
$prodcat = $product->{'category'};
$addline = mysql_query("
insert into dbname(
blah blah
)
VALUES (
blah blah
) ON DUPLICATE KEY UPDATE lowprice='$lowprice', highprice='$highprice'", $db
);
if(!$addline) {
echo "cannot add to table here".mysql_error(); exit; // debug
}
foreach ($xml->product->retailer as $retailer) { // BB
this is another foreach loop but works perfectly
} // close BB
} // close AA
PS: Do you really want to run the BB loop within the AA loop (or do you actually mean to loop over $product->retailer
here)?
I believe the following should work for you. Using ./
in xpath refers to the current node, rather than //
as the root node:
$actors = $products->xpath("./property[name[. ='Actors']]/value");
It may need a little modification for your XML structure, which we can't see. But the key takeaway is using ./
UDPATE
Based on this question, try:
$actors = $products->xpath("./property/value[../name/text() = 'Actors']");
In xpath, starting with '//' means descendant-or-self, starting at the root. You might want to try adding a '.' to the beginning to start at the current node.
$string = file_get_contents('sampleFromPost.xml');
$xml = simplexml_load_string($string);
$groups = $xml->group;
foreach($groups as $group) {
// Changed Actors to Product Title, since Actors doesn't exist in sample.
$title = $group->xpath('.//property[name="Product Title"]/value');
// -- or --
$title = $group->xpath('.//property/value[../name="Product Title"]');
// do something with the value
var_dump($title);
}
精彩评论