Reputation: 3
Here is a snippet of the xml I am working with:
A client requested that we add the ability to filter which type of "news articles" are displayed on specific pages. They create these articles on another website, where they now have the ability to assign a one or more categories to each of the articles. We load the articles via php and xml.
The error I receive is:
Call to a member function getElementsByTagName() on null in ...
Here is the code from 2012 that I am working with:
$item = $dom_object->getElementsByTagName("Releases");
foreach( $item as $value )
{
$Release = $value->getElementsByTagName("Release");
foreach($Release as $ind_Release){
$Title = $ind_Release->getElementsByTagName("Title");
$PublishDateUtc = $ind_Release->getAttribute('PublishDateUtc');
$DetailUrl = $ind_Release->getAttribute('DetailUrl');
$parts = explode('/', $DetailUrl);
$last = end($parts);
I am trying to transverse to the category code and set a variable with:
$newsCategory = $ind_Release->getElementsByTagName("Categories")->item(0)->getElementsByTagName("Category")->item(0)->getElementsByTagName("Code")->item(0)->nodeValue;
This loads the current 2018 articles with the category slug being echoed, because they have an assigned category, but it fails to load 2017, 2016, and so on, I believe, because they are not assigned a category within the XML and this is breaking something.
A news article without a category appears with an empty categories node within XML
I understand that I am using getElementsByTagName, and because there is no element beyond the first categories node it breaks.
Is there a way to check that there is indeed a path to Categories->Category->Code[CDATA] before trying to set it as a variable and breaking it?
I apologize if this is confusing, I am not a PHP expert and could use all the help I can get. Is there a better way to transverse to the needed node?
Thanks.
Upvotes: 0
Views: 782
Reputation: 34628
You need to use XPath. If you're using DOMDocument, this is done via DOMXpath.
Your current approach uses chaining, and the problem with chaining is it breaks down if a particular juncture of it doesn't return what the following method relies on. Hence your error.
Instead, check the whole path from the start:
$domxp = new DOMXpath($dom_object);
$node = $domxp->query('/Categories[1]/Category[1]/Code[1]');
if (count($node)) {
//found - do something
}
Upvotes: 1