17

Say my XML looks like this:

<record>
  <row name="title">this item</row>
  <row name="url">this url</row>
</record>

Now I'm doing something like this:

$xml = new DOMDocument();
$xml->load('xmlfile.xml');

echo $xml->getElementByTagName('row')->item(0)->attributes->getNamedItem('title')->nodeValue;

But this just gives me:

NOTICE: Trying to get property of non-object id

Does anybody know how to get the node value where the "name" attribute has value "title"?

6
  • with XPath: /record/row[@name='title']. Commented Jul 26, 2011 at 9:25
  • Like Michael answered in answer #3. This lookes like the right way to go. But I can't get it to work. Commented Jul 26, 2011 at 10:13
  • see my answer here for a full example with DOM and SimpleXML. Just adapt it to your XML. There is plenty of additional examples on StackOverflow showing DOM usage. Commented Jul 26, 2011 at 10:23
  • Thanks Gordon, but like I said so in others answers I don't want to use a foreach loop due to memory usage of it. Commented Jul 26, 2011 at 10:37
  • if memory is an issue you shouldnt be using DOM in the first place. It will use about ten times the size of the source document because it has to expand the xml into a tree. Try XML Reader then. The foreach is definitely not an issue at all. Commented Jul 26, 2011 at 10:46

3 Answers 3

17

Try:

$xml = new DOMDocument();
$xml->loadXml('
<record>
  <row name="title">this item</row>
  <row name="url">this url</row>
</record>
');

$xpath = new DomXpath($xml);

// traverse all results
foreach ($xpath->query('//row[@name="title"]') as $rowNode) {
    echo $rowNode->nodeValue; // will be 'this item'
}

// Or access the first result directly
$rowNode = $xpath->query('//row[@name="title"][1]')->item(0);
if ($rowNode instanceof DomElement) {
    echo $rowNode->nodeValue;
}
Sign up to request clarification or add additional context in comments.

4 Comments

I don't want to use a foreach. It takes far to much memory to go through the whole XML for this one item.
@Frits The foreach is just an example of how to use the result of $xpath->query (wich will be a DOMNodeList). Also I added some code, to show how you can access the first result directly.
problem is solved with XMLReader as mentioned by Gordon as a comment on my post. Thank you for helping though.
@saravanabawa don't use loadXml to load html, use loadHtml instead.
16
foreach ($xml->getElementsByTagName('row') as $element)
{
if ($element->getAttribute('name') == "title")
{
 echo $element->nodeValue;
}
}

2 Comments

I don't want to use a foreach. It takes far to much memory to go through the whole XML for this one item.
the html I'm working with might not be valid xml, so I appreciate that this solution doesn't rely on treating the html as xml.
3
$xpath = new DOMXPath( $xml );
$val = $xpath->query( '//row[@name="title"]' )->item(0)->nodeValue;

3 Comments

This leaves me with the same php notice. Notice: Trying to get property of non-object in
I tried with your code, worked for me. You'll get the notice if the XPath doesn't match - then item(0) is not a DOMElement and you can't read the nodeValue, hence the message. Do you use namespaces in your XML, or is it the exact same content as you posted it?
problem is solved with XMLReader as mentioned by Gordon as a comment on my post. Thank you for helping though.

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.