Call to a member function xpath() on a non-object? - php

I'm trying to grab an image from a web site using simpleXML and am getting a PHP error saying that I'm trying to call to a member function xpath() on a non-object.
Below are the lines I'm trying to use to get the image's source tag:
$xpath = '/html/body/div/div/div[5]/div/div/div[2]/div/div[2]/img';
$html = new DOMDocument();
#$html->loadHTMLFile($target_URL);
$xml = simplexml_import_dom($html);
$source_image = $xml->xpath($xpath);
$source_image = $source_image[0]['src'];
What am I doing wrong? It's pretty clear the second to last line has a problem, but I'm not sure what it is.

Try this code to first make sure that the document is being parsed correctly.
$xpath = '/html/body/div/div/div[5]/div/div/div[2]/div/div[2]/img';
$html = new DOMDocument();
#$html->loadHTMLFile($target_URL);
$xml = simplexml_import_dom($html);
if (!$xml) {
echo 'Error while parsing the document';
exit;
}
$source_image = $xml->xpath($xpath);
$source_image = $source_image[0]['src'];

Problem solved. Was funning xpath on an empty string.

Related

DOMDocument not updating nodeValue

So I wrote a piece of code which is supposed to be editing the xml file. But it doesn't seem to work. I have checked everything and all data seems to come through, but somehow it does not update the nodes. Creating the xml file and the data works, adding data works too. But somehow I can't seem to update it.
if ($edit && isset($_POST["submit"])) {
$doc = new DomDocument('1.0');
$doc->validateOnParse = true;
$doc->load('data.xml');
$message = getElementById($_GET["id"], $doc);
$message->getElementsByTagName("title")->nodeValue = 'hey';
$message->getElementsByTagName("content")->nodeValue = $_POST["content"];
$target = $message->getElementsByTagName("target")->nodeValue = $_POST["target"];
$date1 = $message->getElementsByTagName("startDate")->nodeValue = $_POST["date1"];
$date2 = $message->getElementsByTagName("endDate")->nodeValue = $_POST["date2"];
$doc->formatOutput = true;
$doc->save('data.xml');
}
function getElementById($id, $doc)
{
$xpath = new DOMXPath($doc);
return $xpath->query("//*[#id='$id']")->item(0);
}
XML:
<message id="5a1c301ae5429" top="12px" left="12px" duration="20">
<title>hey</title>
<content>12345</content>
<target>2</target>
<startDate>27/11/2017 16:30</startDate>
<endDate>27/11/2017 16:50</endDate>
<media type="image" width="200px" height="200px" top="-20px" left="129px">
<uri>
localhost/xml/uploads/4215c27edf5ff51aee0def29f84949be.jpg
</uri>
</media>
</message>
When you call getElementsByTagName, this returns a list of nodes that match the tag name. So each time you access the value, you should use...
$message->getElementsByTagName("title")->item(0)->nodeValue = 'hey';
As you only have 1 of each tag, I've used ->item(0) to fetch the first node in the list.
Repeat the same logic for all times you need to access the elements.

PHP DOMDocument: Fatal error: Call to undefined method DOMElement::save()

I'm trying to indent my XML file, but I can't because of this error.
Why is this problem appear?
This is my code:
<?php
$xmlstr = 'xmlfile.xml';
$sxe = new SimpleXMLElement($xmlstr, null, true);
$lastID = (int)$sxe->xpath("//tip[last()]/tipID")[0] + 1;
$tip = $sxe->addChild('tip');
$tip->addChild('tipID', $lastID);
$tip->addChild('tiptitle', 'Title:');
$sxe->asXML($xmlstr);
$xmlDom = dom_import_simplexml($sxe);
$xmlDom->formatOutput = true;
$xmlDom->save($xmlstr);
?>
I've done a lot of research and I couldn't find an answer.
DOMElement has not method to save xml, but DOMDocument does. Make DOMDocument before:
$xmlDom = dom_import_simplexml($sxe);
$dom = new DOMDocument();
$dom_sxe = $dom->importNode($xmlDom, true);
$dom_sxe = $dom->appendChild($xmlDom);
$Dom->formatOutput = true;
echo $dom->saveXML();
The dom_import_simplexml function returns an instance of DOMElement, which has no save method. What you need instead is a DOMDocument, which does have a save method.
Luckily, it's really easy to get from one to the other, because a DOMElement is a type of DOMNode, and so has an ownerDocument property. Note that the formatOutput attribute is also part of the DOMDocument, so what you need is this:
$xmlDom = dom_import_simplexml($sxe)->ownerDocument;
$xmlDom->formatOutput = true;
$xmlDom->save($xmlstr);

Search within XML with PHP code

this is my code and i am trying to show the value of xml using Xpath but when i run this i am getting error in my code.
Here is the code
<?php
$load = new DOMDocument();
$load = simplexml_load_file("testing.xml");
var_dump($load);
$xpath = new DOMXpath($load);
var_dump($xpath);
$path1 = "/clip/metadata[name=keywords]/value";
$query = $xpath->query($path1);
var_dump("$query");
?>
this is the error, which i am getting
Catchable fatal error: Argument 1 passed to DOMXPath::__construct() must be an instance of DOMDocument, instance of SimpleXMLElement given in C:\xampp\htdocs\xml-text\index.php on line 5
As the error states, you are not passing the constructor the appropriate arguments. simplexml_load_file returns a SimpleXmlElement object, NOT a DOMDocument object.
As stated in the error, you are passing a SimpleXmlElement object instead of a DOMDocument object.
My previous answer was incorrect. It showed how to convert a SimpleXmlElement to a DOMElement not a DOMDocument.
http://php.net/manual/en/domdocument.load.php is how to properly load an xml file into a DOMDocument object.
$load = new DOMDocument();
$load->load("testing.xml");
$xpath = new DOMXpath($load);
Specifically to get the value of the node with the name Keywords you would do something like this
$load = new DOMDocument();
$load->preserveWhiteSpace = false;
$load->load(__DIR__ . "/testing.xml");
$xpath = new DOMXpath($load);
$path1 = '//clip/metadata/name[ . = "Keywords"]';
$query = $xpath->query($path1);
foreach($query as $entry) {
$value = $entry->parentNode->childNodes->item(1)->nodeValue;
}

domDocument extract data

I have a very simple code with domDocumet, but it has a mistake I can't solve:
function getTagXML($mensaje, $tagname){
$dom = new domDocument('1.0', 'UTF-8');
libxml_use_internal_errors(true);
// load the html into the object ***/
$dom->loadHTML($mensaje);
//discard white space
$dom->preserveWhiteSpace = false;
$nodeList= $dom->getElementsByTagName($tagname); // here u use your desired tag
$node = $nodeList->item(0);
$item = trim($node->nodeValue);
libxml_clear_errors();
return $item;
}
I got the error:
Notice: Trying to get property of non-object in line 82:
The line 82:
$item = trim($node->nodeValue);
The error message means that $nodeList isn't an object, which means that $dom->getElementsByTagName($tagname) returned NULL.
Based on your other question I would assume that this happens because your XML document is malformed, that is it's missing a root node.

How to load a xml file in php so that i can use xpath on it?

I have a problem with php,
If I implement this code below then nothing will be happen.
$filename = "/opt/olat/olatdata/bcroot/course/85235053647606/runstructure.xml";
if (file_exists($filename)) {
$xml = simplexml_load_file($filename, 'SimpleXMLElement', LIBXML_NOCDATA);
// $xpath = new DOMXPath($filename);
}
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXpath($doc);
$res = $xpath->query('/org.olat.course.Structure/rootNode/children/org.olat.course.nodes.STCourseNode/shortTitle');
foreach ($res as $entry) {
echo "{$entry->nodeValue}<br/>";
}
If I change the contents of $xml in the content with the content of the $filename
$xml = '<org.olat.course.Structure><rootNode class="org.olat.course.nodes.STCourseNode"> ... ';
then it works, so i think that there is something wrong with loading methode of the xml file,
I've also tried to load the xml file as a Domdocument but it won't work neither.
And in both cases, it does work if I collect xml data via xml
for example this works
echo $Course_name = $xml->rootNode->longTitle;
loadXML takes a string as input, not the return value of simplexml_load_file. Just use file_get_contents to get the (full) contents of a file as string

Categories