1

I'm trying to read an XML file with PHP but I'm only getting the first result and can't figure out why.

XML structure:

<main>
  <data>
   <record>
    <column name="title">Some title here</column>
   </record>
   <record>
    <column name="title">Some second title here</column>
   </record>
  </data>
</main>

Pretty basic. This is the code I'm using to getting the results:

foreach($XML->data->record as $product) {
  $title = mysql_real_escape_string($product->title);
}

But this only gives an empty string so I guess I'm looking at the wrong path. The code below does work, but only gives me the first record and not the other records in the XML file.

foreach($XML->data as $product) {
  $title = mysql_real_escape_string($product->record->title);
}

The answer is probably easy, but I can't figure it out. Hope someone is willing to help :)

MNL
  • 101
  • 10
  • How are you loading the xml file to $XML in your code ? – Cihan Uygun Jan 22 '16 at 15:43
  • 1
    you **SURE** It's an empty string, not boolean false? you have to be connected to mysql to use that function, and the entire `mysql_*()` function-set is obsolete anyways. You shouldn't be using it in any new code. – Marc B Jan 22 '16 at 15:45

2 Answers2

2

title is the value of the name attribute of the <column> node.
You can't access it the way you do it.

To access the <column> node:

$xml = simplexml_load_string($x); // assume XML in $x

foreach ($xml->data->record as $product) {
    echo $product->column;
}

Output:

Some title here
Some second title here

see it working: https://eval.in/506519

If there are many columns under each record...

<record>
    <column name="title">Some title here</column>
    <column name="car">BMW</column>
    <column name="color">red</column>
</record>

... and you want to list all, you need a second loop:

foreach ($xml->data->record as $product) {  // same as above
    foreach ($product->column as $column) { // iterate all column 
        echo $column['name'] . ": " . $column . PHP_EOL;
    }
}

Output:

title: Some title here
car: BMW
color: red

see it working: https://eval.in/506521

In case you want only <column> nodes with name = "title", check with if:

foreach ($xml->data->record as $product) {  // same as above
    foreach ($product->column as $column) { // iterate all column 
        if ($column['name'] == "title") echo $column . PHP_EOL;
    }
}

see it working: https://eval.in/506523

And be aware that there is a different way to get all <column> with name = "title" with xpath:

$titles = $xml->xpath("//column[@name = 'title']");
foreach ($titles as $title)
    echo $title . PHP_EOL;

see it in action: https://eval.in/506531

For an explanation of the xpath syntax, look at Using xPath to access values of simpleXML and zillion others.

and BTW: as said in comments, don't use mysql_...

Community
  • 1
  • 1
michi
  • 6,565
  • 4
  • 33
  • 56
0

Not tested but looks ok. Load the xml file / string into DOMDocument and get all the column nodes and iterate through them

$dom=new DOMDocument;
$dom->loadXML( $strxml );
/*
    or
    --
$dom->load( $xmlfile );
*/

$col=$dom->getElementsByTagName('column');
foreach( $col as $node ){
    echo $node->tagName.' '.$node->getAttribute('title').' '.$node->nodeValue;
}
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46