get elements by name from a DOMNodeList - php

In the following code, I retrieve with DOM a list of nodes from an xml document. Then I would like to select, by their tag name, some of these nodes.
$index = new DOMDocument();
$index->load('index.xml');
$xpath = new DOMXpath($index);
$related_notions = $xpath->query("/index/notion[name='" . $name . "']/relations/*"); // the variable $name is dynamically defined previously in the script
foreach ($related_notions->getElementsByTagName("superordinate") as $item) {
// do something
}
I get the following error: Uncaught Error: Call to undefined method DOMNodeList::getElementsByTagName()
I don't understand why the method getElementsByTagName() is not defined for DOMNodeList. After all, getting elements by their name seems to me something obvious that one might want to do with a node list. At any rate, my actual question is: How can I do what I want to do? That is, in the absence of the method getElementsByTagName(), how do I get elements by tag name from a node list?
Thanks in advance for your help!

I found a solution to my problem, namely to test for the nodeName with an if statement inside the foreach:
$index = new DOMDocument();
$index->load('index.xml');
$xpath = new DOMXpath($index);
$related_notions = $xpath->query("/index/notion[name='" . $name . "']/relations/*");
foreach ($related_notions as $item) {
if ($item->nodeName == "superordinate") {
// do something
}
}

Related

How can I use "getElementsByTagName" on a DOMElement in PHP?

How can I use a getElementsByTagName() on a DOMElement in PHP?
I want to go through the second cell, td, in every row, tr, in a table to get the rows title:
function getDetails($url) {
$doc = new DOMDocument();
#$doc->loadHTML(file_get_contents($url));
$table = $doc->getElementById("table");
$rows = $doc->getElementsByTagName("tr");
foreach ($rows as $row) {
$items = $row->getElementsByTagName("td");
$title = $items->item(1)->getElementsByTagName('a')->item(0)->nodeValue;
}
}
Although, when I try to run it I get this error on $title = $items->item(1)->getElementsByTagName('a')->item(0)->nodeValue;:
Fatal error: Uncaught Error: Call to a member function getElementsByTagName() on null
I've tried to find a solution to the problem but didn't find anything. Do anyone know how I can fix this or should I do it in another way?

php echo DOM Elements as strings

I have used the following code to store a small timetable in an array. I am trying to return specific elements of the array but get the error Cannot use object of type DOMElement as array.
I would be grateful if somebody could tell me how to retrieve the nodeValue of certain elements and display them.
$doc = new DOMDocument();
$doc->loadHTML($timetable);
$headers = $doc->getElementsByTagName('th');//' missed which is typo i think
$cells = $doc->getElementsByTagName('td');//' missed which is typo i think
$array = iterator_to_array($cells);
I can loop through this and display the entire table with a for loop, and that's fine, but I can't return 1 value from the array:
for ($i=0; $i<=5; $i++){
$val = $array[$i];
echo $val[1]->nodeValue;
}
And this returns the error I mentioned above.

getting value of custom attributes using XPATH and PHP

I am trying to extract the data stored in a list. The troubling piece is the "custom-data" entity.
<li id="myid" custom-data="123456789" class="search-query">
...lots of child elements
I get all the string data with querying DomXPath object for "search-query" and than extract it with this the code below.
$id = $exampleXPath->query("//li[#class='search-query']");
foreach ($id as $element) {
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo "$node->nodeValue<br>";
}
}
I would like to also get the value of "custom-data" of each "search-query" object, but I don't how to get it. Any ideas?
You already have reference to all "search-query" elements, so getting the attribute should be as straightforward as calling getAttribute("attribute_name") on each element:
$custom_data = $element->getAttribute("custom-data");

Check if XML element is existing in loop

For a website i'm making i need to get data from an external XML file.
I load the data like this:
$doc = new DOMDocument();
$url = 'http://myurl/results/xml/12345';
if (!$doc->load($url))
{
echo json_encode(array('error'=> 'error'));
exit;
}
$xpath = new DOMXPath($doc);
$program_date = $xpath->query('//game/date');
Then i use a foreach loop to get all the data
if($program_date){
foreach($program_date as $node){
$programArray['program_date'][] = $node->nodeValue;
}
}
The problem i'm having is that sometimes a certain game doesn't have a date.
So when a game doesn't have a date, i just want it to put "-", instead of the date from the XML file. My problem is that i don't know how to check if a date is present in the data.
I used a lot of ways like isset, !isset, else, !empty, empty
$teamArray['program_kind'][] = "-";
but noting works...
Can someone help me with this problem?
Thanks in advance
You need to iterate the game elements, use them as a context and fetch the data with additional XPath expressions.
But one thing first. Use DOMXPath::evaluate(). DOMXPath::query() only supports location paths. It can only return a node list. But XPath expressions can return scalar values, too.
$xpath = new DOMXPath($doc);
$games = $xpath->evaluate('//game');
The result of //game will always be a DOMNodeList object. It can be an empty list, but you can directly iterate it. A condition like if ($games) will always be true.
foreach ($games as $game) {
Now that you have the game element node, you can use it as an context to fetch other data.
$date = $xpath->evaluate('string(date)', $game);
string() casts the first node of the location path into a string. If it can not match a node, it will return an empty string. Check normalize-space() if you want to remove whitespaces at the same time.
You can validate if the game element has a date node using count().
$hasDate = $xpath->evaluate('count(date) > 0', $game);
The result of this XPath expression is always a boolean.

PHP Dom: nodeValue read as object instead of string

I'm trying to pull the links off of a bunch of webpages and report them in tables. I have this function, get_links($pageId), which is supposed to get the contents of the page and pull out the values and href attributes of each anchor tag.
function get_links($pageId) {
$page_contents = file_get_contents('http://www.mysite.com/?p='.$pageId);
$html = new DOMDocument();
#$html->loadHTML($page_contents);
$anchors = $html->getElementsByTagName('a');
$link_array = array();
foreach($anchors as $anchor) {
if (!empty($anchor->nodeValue)) {
$text = $anchor->nodeValue;
$link = $anchor->getAttribute('href');
$link_array[$text] = $link;
}
}
return $link_array;
}
When I run this function on one of the pages, it returns nothing. For example, if I call:
$page_links = get_links('someId');
foreach($page_links as $text->$link) {
//my print functions
};
I get "Fatal error: Cannot access empty property" for the foreach line.
Echoing $text and $link in the foreach($anchors) loop works fine. So does echoing the values from $link_array after the loop. But echoing the keys doesn't. If I put in this test right after the loop:
foreach($link_array as $text->$link) {echo $text;}
I get this error: "Catchable fatal error: Object of class stdClass could not be converted to string."
Why would it print alright during the loop but be treated as an object when I put it in an array to return?
You're trying to assign the iterated valutes of the foreach loop to an object's attribute. I think you actually want
foreach($link_array as $text => $link) { echo $text;}
instead.
Saying $text->$link is telling PHP to take the current foreach iterated value, and assign it to a $link property of the $text object - however, $text and $link are not objects at that point, so you're assigning to non-existence attributes of a non-existent object, causing the "Cannot access empty property" error.

Categories