1

How can I get each node's attribute via xpath?

For instance,

book.xml,

<?xml version="1.0" encoding="UTF-8" ?>
<records timestamp="1264777862">
<record></record>
<record></record>
<record timestamp="1264777000"></record>
<record></record>
</records>

php,

<?php

$doc = new DOMDocument;

$doc->load('book.xml');

$xpath = new DOMXPath($doc);

# get and output "<entry>" elements
$x = $doc -> getElementsByTagName('record');

# Count the total feed with xpath.
$total = $x->length;

# the query is relative to the records node
$query = 'string(/records/@timestamp)';

for ($i=0; $i<$total; $i++)
{
    $timestamp = $xpath->evaluate($query,$x->item($i));
    echo $timestamp ."<br/>";
}

?>

result (which it loops the first node only),

1264777862
1264777862
1264777862
1264777862

But I want to get,

1264777862
1264777000

I have followed the question and answer from here and modified from it.

Or maybe there are better methods?

EDIT:

xml,

<?xml version="1.0" encoding="UTF-8" ?>
<records>
    <record timestamp="1264777862">A</record>
    <record>B</record>
    <record timestamp="1264777000">C</record>
    <record>D</record>
</records>

with this,

for ($i=0; $i<$total; $i++)
{
    $value = $x->item($i)->childNodes->item(0)->nodeValue;
    $timestamp = $xpath->evaluate($query,$x->item($i));
    echo $value.': '.$timestamp ."<br/>";
}

I get this result,

A: 1264777862
B: 1264777862
C: 1264777862
D: 1264777862

but this is the result I am after,

A: 1264777862
B: 
C: 1264777862
D: 

EDIT:

a test,

$nodes = $xpath->query('//records/record');

foreach($nodes as $node) {
    $value = $node->nodeValue;
    $timestamp = $node->getAttribute('timestamp');
    echo $value .': '."<br/>";
}

result,

A: 
B: 
C: 
D: 
2
  • Your XML has an attribute on records and one on record. Which are you trying to work with? Commented Nov 9, 2011 at 15:52
  • sorry my mistake. please see my edit above. thanks. Commented Nov 9, 2011 at 16:03

1 Answer 1

4

One method:

$nodes = $xpath->query('//records[@timestamp]');
foreach($nodes as $node) {
    $timestamp = $node->getAttribute('timestamp');
}

Though, you've mixed record and records in your example, so I'm not sure which you're using in reality.


update: This code works for me:

<?php

$xml = <<<EOL
<?xml version="1.0" encoding="UTF-8" ?>
<records>
    <record timestamp="1264777862">A</record>
    <record>B</record>
    <record timestamp="1264777000">C</record>
    <record>D</record>
</records>
EOL;

$x = new DOMDocument();
$x->loadXML($xml);

$xp = new DOMXpath($x);

$nodes = $xp->query('//records/record');
foreach($nodes as $node) {
   echo $node->nodeValue, ': ', $node->getAttribute('timestamp'), "\n";
}

and outputs

A: 1264777862
B:
C: 1264777000
D:
Sign up to request clarification or add additional context in comments.

6 Comments

sorry, my mistake. please see my edit above. I get an error message with getAttrribute thanks.
woops. typo. Should be getAttribute (one r).
sorry, I just realised another problem as I need more information in the result. I cannot use the query u in your answer I guess. can u please see my edit above? thanks.
So you want to output all record nodes, whether they have a timestamp attribute or not? Use //records as the xpath, then $node->nodeValue to get the a/b/c/d stuff.
how can I use getAttribute('timestamp') after that? please see my edit above. thanks.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.