SimpleXML question

Hi,

Been battling with this for most of today so would be very grateful for some help.

I’ve used simplexml_load_file to load up my xml.

Simplified version of problem:



foreach ($xml->level1->level2->level3->level4 as $nodes) {
//process the nodes
}


The above would get me to all the last children that I want to process.

However, if level2 contains two attributes i.e.
[xml]
<level2 name=“name1”>
<level3>

</level3>
<level2 name=“name2”>
<level3>

</level3>
[/xml]

How should I rewrite my foreach statement to filter the name1 children only.

I suspect and hope that this isn’t as difficult as I have found it.

This might not be what you’re looking for but a simple approach would be the following:

foreach ($xml->level1->level2->level3->level4 as $nodes) {
   if(preg_match(/name1/i))
      /* Perform Action... */
}

Someone else around here might have a better, more dynamic and efficient approach…

I obviously misread your question… Hopefully someone will come on here and help out. My bad.

Thanks Wolf,

I might have made a small breakthrough with this. I was trying to control the path through to the leaf nodes using xpath where the attribute splits the path, but with no success.

However I can get this control using level2[0]->level3 etc and can take a count at each of the levels to loop through and find the attribute value so that I know the attribute of the node the children belong to.

Hopefully that will allow me to nail this. Might not be the tidiest solution and your suggestion might prove useful as an option or check, so appreciate you taking the time to respond.

Hi Arthur,

If I read your first post correctly your example doesnt constitute a valid xml format.

Can you give the real world example of you file your parsing.

So your XML looks something like this?

<level2 name="name1">
<level3>value1</level3>

<level2 name="name2">
<level3>value2</level3>

I would have expected something like this???

<level2 name="name1">
<level3>value1</level3>
</level2>

<level2 name="name2">
<level3>value2</level3>
</level2>

Colin

Apologies,

Yes, my shorthand version of the xml should have read as per Colin’s above. The actual example is more complicated but this sums up the challenge I’m struggling with.

Thanks for the feedback.

Can you post the actual feed.

:slight_smile:

Hi Colin,

Grateful for your attempts to help.

Here’s the feed:

[xml]

<?xml version=“1.0” encoding=“UTF-8” ?>

  • <getHistogramsResponse xmlns=“http://www.ebay.com/marketplace/search/v1/services”>
    <ack>Success</ack>
    <version>1.10.0</version>
    <timestamp>2011-03-02T22:28:32.879Z</timestamp>
  • <aspectHistogramContainer>
    <domainName>Video_Games_Games</domainName>
    <domainDisplayName>Video Games</domainDisplayName>
    - <aspect name=“Platform”>
  • <valueHistogram valueName=“Sony PlayStation”>
    <count>68065</count>
    </valueHistogram>
  • <valueHistogram valueName=“PC”>
    <count>64988</count>
    </valueHistogram>

  • <valueHistogram valueName=“Microsoft Xbox 360 Elite”>
    <count>5</count>
    </valueHistogram>
  • <valueHistogram valueName=“Not Specified”>
    <count>56076</count>
    </valueHistogram>
    </aspect>
    - <aspect name=“Genre”>
  • <valueHistogram valueName=“Action, Adventure”>
    <count>148365</count>
    </valueHistogram>
  • <valueHistogram valueName=“Arcade”>
    <count>5067</count>
    </valueHistogram>
  • <valueHistogram valueName=“Virtual Pet”>
    <count>2302</count>
    </valueHistogram>
  • <valueHistogram valueName=“Not Specified”>
    <count>196414</count>
    </valueHistogram>
    </aspect>
    - <aspect name=“Rating”>
  • <valueHistogram valueName=“EC - Early Childhood”>
    <count>1107</count>
    </valueHistogram>
  • <valueHistogram valueName=“E - Everyone”>
    <count>233215</count>
    </valueHistogram>
    </aspect>
    </aspectHistogramContainer>
    </getHistogramsResponse>

[/xml]

In case it might be of interest or use to others - here’s what I ended up with which seems to be working fine



$cat_id="100";
$full_path='xml_generator.php'.'?CategoryID='.$cat_id;
$url=simplexml_load_file($full_path);

//find out the number of aspect nodes
//this is the trunk point where the 'name' attribute can have different values
$noAspectHistograms=count($url->aspectHistogramContainer->aspect);

//check that the category has not already been mapped - external function
$CategoryMapping=isCategoryMapped($cat_id);
//only precede if category is unmapped
if ($CategoryMapping=="unmapped") {

//loop through the Aspect Nodes to find all their children
$i=0;
foreach ($url->aspectHistogramContainer->aspect as $aspect) {
foreach ($aspect->attributes() as $aspectName=>$aspectValue) {
// insert into table1 values for cat_id and aspectValue
// use mysql_insert_id() to get the rowID to use as the aspectID in the second insert query
$aspectID=mysql_insert_id();
}
foreach ($url->aspectHistogramContainer->aspect[$i]->valueHistogram as $nodes) {
foreach ($nodes->attributes() as $HistName=>$HistValue) {
// insert into table2 values for aspect_id and HistValue

}
}
$i++;
}
}