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;
}
Related
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);
Creating the DOMDocument object:
$getToken = '<getToken>...</getToken>';
$getToken_objeto = new DOMDocument("1.0", "UTF-8");
$getToken_objeto -> loadXML($getToken);
Trying to append a XML string (Signature) into the DOMDocument created above:
$Signature = '<Signature>...</Signature>';
$Signature_objeto = new DOMDocument("1.0", "UTF-8");
$Signature_objeto -> loadXML($Signature);
$Signature_nodeList = $Signature_objeto -> getElementsByTagName("Signature");
$Signature_node = $Signature_nodeList -> item(0);
$getToken_objeto -> importNode($Signature_node, true);
$getToken_objeto -> appendChild($Signature_node);
I get 2 errors:
Fatal error: Uncaught exception 'DOMException' with message 'Wrong Document Error' in C:...
DOMException: Wrong Document Error in C:...
Seems simple to resolve but im quite unexperienced using the PHP DOM extension.
Thanks in advance.
You're trying to append the original node - not the imported one.
$Signature_node = $getToken_objeto->importNode(
$Signature_nodeList->item(0), true
);
You're trying to append the node to the document, but an XML document can only have a single document element and it already has one. You can append it to the document element:
$getToken_objeto->documentElement->appendChild($Signature_node);
But PHP can load XML fragments directly into a DOMDocumentFragment.
$xml = '<getToken>...</getToken>';
$fragmentXml = '<Signature>...</Signature>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);
$fragment = $dom->createDocumentFragment();
$fragment->appendXml($fragmentXml);
$xpath
->evaluate('//getToken')
->item(0)
->appendChild($fragment);
echo $dom->saveXml();
I have the following response from a XML api , I want to display the text that is placed in the comments section .
<OTA_AirDetailsRS PrimaryLangID="eng" Version="1.0" TransactionIdentifier=""><Errors><Error Type="ERR" FLSErrorCode="-10" FLSErrorName="Invalid Input"/></Errors><!-- Reason for error: The Date parameter is not valid [2014-05-16] --></OTA_AirDetailsRS>
I have used this :
...
$query = curl_exec($curl_handle);
curl_close($curl_handle);
$xml = new SimpleXmlElement($query);
if($xml->Errors){
$doc = new DOMDocument;
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//comment()') as $comment)
{
var_dump($comment->textContent);
}
Its not displaying anything in this case , but if instead of passing xml response , I pass it a simple xml in string format , it is working . Please suggest if something is wrong.
You need to load the XML, not the object from your SimpleXmlElement call:
$doc = new DOMDocument;
$doc->loadXML($query);
Then your script outputs:
string(64) " Reason for error: The Date parameter is not valid [2014-05-16] "
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.
A web service return Xml of format
<string>
<NewDataSet>
<DealBlotter>
<CustomerReference>161403239</CustomerReference>
<Symbol>EUR/USD</Symbol>
<BuySell>S</BuySell>
<ContractValue>-100000</ContractValue>
<Price>1.35070</Price>
<CounterValue>-135070</CounterValue>
<TradeDate>2011-01-20 22:05:21.690</TradeDate>
<ConfirmationNumber>78967117</ConfirmationNumber>
<Status>C</Status>
<lTID>111913820</lTID>
</DealBlotter>
</NewDataSet>
</string>
Now i am using curl to access this and then -
$xml = simplexml_load_string($result);
$dom = new DOMDOcument();
// Load your XML as a string
$dom->loadXML($xml);
// Create new XPath object
$xpath = new DOMXpath($dom);
$res = $xpath->query("/NewDataSet/DealBlotter");
foreach($res as $node)
{
print "i went inside foreach";
$custref = ($node->getElementsByTagName("CustomerReference")->item(0)->nodeValue);
print $custref;
$ccy = ($node->getElementsByTagName("Symbol")->item(0)->nodeValue);
print $ccy;
$type = ($node->getElementsByTagName("BuySell")->item(0)->nodeValue);
$lots = ($node->getElementsByTagName("ContractValue")->item(0)->nodeValue);
$price = ($node->getElementsByTagName("Price")->item(0)->nodeValue);
$confnumber = ($node->getElementsByTagName("ConfirmationNumber")->item(0)->nodeValue);
$status = ($node->getElementsByTagName("Status")->item(0)->nodeValue);
$ltid = ($node->getElementsByTagName("lTID")->item(0)->nodeValue);
$time = ($node->getElementsByTagName("TradeDate")->item(0)->nodeValue);
}
But nothing is getting printed. except the dummy statement.
using $res = $xpath->query("/string/NewDataSet/DealBlotter"); did not help. Also a print_r($res); gives output as DOMNodeList obect.
Doing this also does not print anything
$objDOM = new DOMDocument();
$objDOM->load($result);
$note = $objDOM->getElementsByTagName("DealBlotter");
foreach( $note as $value )
{
print "hello";
$tasks = $value->getElementsByTagName("Symbol");
$task = (string)$tasks->item(0)->nodeValue;
$details = $value->getElementsByTagName("Status");
$detail = (string)$details->item(0)->nodeValue;
print "$task :: $detail <br>";
}
There are a few problems.
With how you're loading the xml. Get rid of the simplexml line. It's not needed, and is messing things up. Instead just do $dom->loadXml($result);. There's no reason to load SimpleXML first if you're going to pass it directly into DomDocument.
With your query, the / operator is the direct decendent operator. So it means directly next to. So your first tag should be the root. So either add the root onto it:
$res = $xpath->query("/string/NewDataSet/DealBlotter");
Or make the leading slash into // which selects any matching decendent:
$res = $xpath->query("//NewDataSet/DealBlotter");
And finally, doing a var_dump on $res isn't going to tell you much. Instead, I like to do var_dump($res->length) since it'll tell you how many matches it has rather than that it's a domnodelist (which you already know)...