The Curse of XML and PHP Whitespace - php

I am having an issue with DOMDocument and whitespace. Currently I have two types of XML files. One file was created manually about a year ago, I will call this file A. The second file, file B, is being generated using a PHP DOMDocument. I have been trying very hard (unsuccessfully) to make the whitespace in file A match file B.
Here's how it works... The user is given an option to add new <Slide> elements to the XML file. After new slides have been added the user has the option to add new <Items> to the XML file as a child of the <Slide> element.
When I add a <Slide> element to file B it works like a charm. I can even add a new <Item> element with zero problem. However, when I try to access the new <Identifier> element I just added in file B using the second PHP script below with $order != 'remove' I miss the node by one and select <Information/> instead.
It appears that manually created file A has white space that is not present in my generated file B. I have experimented with the preserveWhitespace property but it did not help.
Are there any suggestions on how I can correct this problem. Constructive criticism is also welcome as this is my first shot at dynamic XML manipulation. I apologize for the length and appreciate your time!!
File A - Created Manually - I am trying to match this file!
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Areas>Head & Neck</Areas>
<Area>Head & Neck</Area>
<Type>Angiograph</Type>
<Slide>Ag-01a
<Title>Catheter Angiography</Title>
<Item1>
<Identifier interestCoord=".51,.73" locator="point" labelBool="true" labelTxt="" leaderBool="true">Aortic Arch
</Identifier>
<Information/>
<Question A="" B="" C="" D="" E="" Answer=""/>
</Item1>
.... More Items
File B - Before user adds <Slide>. This portion is created Manually. A template if you will. After the user enters slide names new slides are generated using the chunk of code below.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Areas>Head & Neck</Areas>
<Area>Head & Neck</Area>
<Type>Brain Sections</Type>
</root>
File B - After users adds new <Slide> and <Item>. Formatting shown represents formatting created by DOMDocument. I think this is where the error is occuring! Whitespace!!!
<Slide>Ag-09a
<Title>Catheter Angiography</Title>
<Item1><Identifier locator="point" interestCoord="0.143,0.65" labelBool="true" labelTxt="" leaderBool="false">Orbit</Identifier><Information/><Question A="" B="" C="" D="" E="" Answer=""/></Item1></Slide>
PHP script used to add new <Slide> elements to XML
<?php
session_start();
//Constants
$SECTION_SEP = "========================================================================</br>";
//Variables used to construct file path
$area = trim($_POST['area']);
$slideType = trim($_POST['slideType']);
$rawSlides = trim($_POST['theseSlides']);
$newSlideList = explode(",", $rawSlides);
$fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML";
$dom = new DOMDocument();
echo('New DOMDocument created!</br>');
$dom->load($fileLocation);
echo('XML file loaded!</br>');
/*$dom->preserveWhiteSpace = false;
echo('White space removed!</br>');*/
$dom->documentElement;
echo('DOM initialized!</br>');
if ($dom->getElementsByTagName('Slide')->length == 0){ //New file with no slides
foreach ($newSlideList as $slide){
$newSlide = $dom->createElement('Slide', $slide);
$newTitle = $dom->createElement('Title', 'Scan');
//Add the title element to the Item
$newSlide->appendChild($newTitle);
$dom->childNodes->item(0)->appendChild($newSlide);
echo($slide." has been added to the list!</br>");
}
} else {
$locators = $dom->getElementsByTagName('Slide');
}
if($dom->save($fileLocation)){
echo("File saved successfully!!");
}else echo("There was a problem saving the file!");
PHP script used to add/edit/remove <Item> and <Identifier> nodes depending on value of $orders == WARNING! Lengthy :/
<?php
session_start();
//Constants
$SECTION_SEP = "========================================================================</br>";
//Variables used to construct file path
$area = trim($_POST['area']);
$slideType = trim($_POST['slideType']);
$fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML";
//echo("File location:".$fileLocation);
//Current data (c_ for current)
$c_poi = "";
$c_type = "";
$c_lblBool = "";
$c_lblOverride = "";
$c_leaderBool = "";
//Determine if this visit is for new or old data
$orders = trim($_POST['orders']);
//Variables used to replace information in XML file loaded below (n_ for new)
$n_slideName = trim($_POST['slideName']); //slide name in view format ie Ag-01a
$n_identName = trim($_POST['ident']); //contains multiple information separated by comma ie 0,Aortic Arch
$n_type = trim($_POST['type']); //locator type
$n_poi = trim($_POST['poi']);
$n_lblBool = trim($_POST['lblBool']);
$n_lblOverride = trim($_POST['lblOverride']);
echo("Modified: ".date('c')."</br>");
$dom = new DOMDocument();
echo('New DOMDocument created!</br>');
$dom->load($fileLocation);
echo('XML file loaded!</br>');
/*$dom->preserveWhiteSpace = false;
echo('White space removed!</br>');*/
$dom->documentElement;
echo('DOM initialized!</br>');
$locators = $dom->getElementsByTagName('Slide');
echo($locators->length.' elements retrieved</br>');
$slideEntryFound = false;
$identEntryFound = false;
$identAttributesFound = false;
echo($SECTION_SEP);
//Locate the correct slide node
foreach ($locators as $locator){
//If there is a match, store the infomation
// rawSlide[x].childNode[0].nodeValue
if(strcmp(trim($locator->childNodes->item(0)->nodeValue),$n_slideName) == 0){
$slideEntryFound = true;
$slideChildren = $locator->childNodes;
//Locate the correct identifier node
foreach($slideChildren as $child){
if( strcmp(trim($child->nodeValue), substr($n_identName,strpos($n_identName,",")+1)) == 0){
$identEntryFound = true;
if (strcmp($orders, "remove") == 0){//Removing an element
echo("The identifier being removed is: ".trim($child->nodeValue."</br>"));
echo("The node path is: ".($child->childNodes->item(1)->getNodePath())."</br>");
echo($SECTION_SEP);
$locator->removeChild($child);
echo("Identifier successfully removed!</br>");
echo($SECTION_SEP);
break;
} else {//Not removing anything - Adding or Editing
echo("The identifier being modified is: ".trim($child->nodeValue."</br>"));
echo("The node path is: ".($child->childNodes->item(1)->getNodePath())."</br>");
echo($SECTION_SEP);
if($child->childNodes->item(1)->hasAttributes()){
$identAttributesFound = true;
$c_poi = $child->childNodes->item(1)->getAttribute('interestCoord');
echo("--Current interestCoord: ".$c_poi."</br>");
echo("++New interestCoord: ".$n_poi."</br>");
if(strcmp($c_poi, $n_poi) != 0){
$child->childNodes->item(1)->setAttribute('interestCoord',$n_poi);
}
$c_type = $child->childNodes->item(1)->getAttribute('locator');
echo("--Current locator: ".$c_type."</br>");
echo("++New locator: ".$n_type."</br>");
$c_lblBool = $child->childNodes->item(1)->getAttribute('labelBool');
echo("--Current labelBool: ".$c_lblBool."</br>");
//echo("++New labelBool: ".$n_lblBool."</br>");
$c_lblOverride = $child->childNodes->item(1)->getAttribute('labelTxt');
echo("--Current labelOverride: ".$c_lblOverride."</br>");
echo("++New labelOverride: ".$n_lblOverride."</br>");
$c_leaderBool = $child->childNodes->item(1)->getAttribute('leaderBool');
echo("--Current leaderBool: ".$c_leaderBool."</br>");
//echo("++New leaderBool: ".$n_leaderBool."</br>");
if($n_lblOverride != ""){
echo("**A new label override was detected. The identifier will have the alias ".$n_lblOverride.".");
}
break;
} else echo("Fatal Error - Node does not contain attributes!</br>");
if($identEntryFound == true && $identAttributesFound == false)
echo("Error - Attribute entry not found!");
break;
}
}
}
if($slideEntryFound == true && $identEntryFound == false && $orders != "remove"){
echo("The identifier was not found... creating a new identifier!</br>");
//Create a new Element
$newElement = $dom->createElement("Item".((integer)(substr($n_identName,0,strpos($n_identName,",")))+1));
echo("New element created!!</br>");
//Create new Item children
$newSubElem = $dom->createElement("Identifier", substr($n_identName,strpos($n_identName,",")+1));
$newSubElem->setAttribute('locator',$n_type);
$newSubElem ->setAttribute('interestCoord',$n_poi);
$newSubElem->setAttribute('labelBool', $n_lblBool);
$newSubElem->setAttribute('labelTxt', $n_lblOverride);
//TODO link this next one to a variable instead of hard coding
$newSubElem->setAttribute('leaderBool', "false");
//Info Child
$newInfoElem = $dom->createElement("Information");
//Question Child
$newQuestion = $dom->createElement("Question");
$newQuestion->setAttribute('A', "");
$newQuestion->setAttribute('B', "");
$newQuestion->setAttribute('C', "");
$newQuestion->setAttribute('D', "");
$newQuestion->setAttribute('E', "");
$newQuestion->setAttribute('Answer', "");
//Add new children to main Item
$newElement->appendChild($newSubElem);
$newElement->appendChild($newInfoElem);
$newElement->appendChild($newQuestion);
$locator->appendChild($newElement);
echo("New identifier added!!</br>");
break;
}
} else {
}
}
if($slideEntryFound == false)
echo("Error - Slide entry not found!");
if($dom->save($fileLocation)){
echo("File saved successfully!!");
echo('<div id="phpHandleBtns>"></br><form><button type="submit" id="continueEdit" formaction="../edit.php">Continue Editing</button>'.
'</br><button type="submit" id="doneEdit" formaction="../main.php">Done Editing</button></form></div>');
}else echo("There was a problem saving the file!");
?>

I would strongly recommend that you use an XPath API like this http://php.net/manual/en/class.domxpath.php to find the nodes you are interested in. Attempting to use the DOM API directly is only going to cause you heartache.
More specifically, I think that your call to childNode() is getting tripped up by white space, but if you used childElement() instead (not sure if that exists, but with XPath it is easy), it would just ignore any whitespace.

Related

Save XML file without Declaration - with specific address

I am trying to find a way to save the XML file once edited, without including the declaration. But i need to be able to set an address. As i am saving over the original XML, and saving over a temp location one (duplicate of the original for javascript to access, as the original is in a local file).
So i tried the $dom->saveXML($xml->documentElement); but comes out with some save errors.
This is the php page that gets the form data and saves it to the currently loaded xml, then saves it and another copy (Down the bottom of the below code)
<?php
//header('Location: ../index.php' );
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load("../data/fileloc.xml");
$fileUrlTag = $dom->getElementsByTagName('fileurl')->item(0);
$fileName = $fileUrlTag->getAttribute('filename');
$fileAddress = $fileUrlTag->getAttribute('address');
$fileUrl = $fileAddress.$fileName;
if(isset($_REQUEST['ok'])){
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->load($fileUrl);
//checks if Objects tag exists
$rootTag = $xml->getElementsByTagName("Objects")->item(0);
//if Objects tag doesnt exist, creates it and a unique id
if($xml->getElementsByTagName("Objects")->length == 0){
$rootTag = $xml->createElement("Objects");
$alph = "0123456789ABCDEF";
$ranStr = '';
for($i=0;$i<32;$i++){
if($i==8 || $i==12 || $i==16 || $i==20){
$ranStr .= "-";
}
$pos = rand(0,35);
$ranStr .= $alph[rand(0, strlen($alph)-1)];
};
$randId = "{".$ranStr."}";
$rootTag->setAttribute("OverlayId",$randId);
$objDocTag = $xml->getElementsByTagName("ObjectsDoc")->item(0);
if($objDocTag->getAttribute("Version")->length == 0){
$objDocTag->setAttribute("Version","1.0");
};
$objDocTag->appendChild($rootTag);
};
//used to set ID on Layer tag - gets value from the Objects->OverlayId attribute
$getId = $rootTag->getAttribute('OverlayId');
//used to set ID on Object tag
$numObj = $xml->getElementsByTagName('Object')->length;
//commstag determines colours for Pen and Brush tags
$commsTag = $xml->createElement("comms",$_REQUEST["comms"]);
//convert from deg to radians
$lat = $_REQUEST['lat'];
$long = $_REQUEST['long'];
$latRad = ($lat*6.28318)/360;
$longRad = ($long*6.28318)/360;
if($_REQUEST['comms']=='Good'){
$color = array(255,0,255,0);
};
if($_REQUEST['comms']=='Bad'){
$color = array(255,0,255,255);
};
if($_REQUEST['comms']=='None'){
$color = array(255,0,0,255);
};
//Create object and set object attributes
$objectTag = $xml->createElement("Object");
$objectTag->setAttribute("ID",($numObj+1000));
$objectTag->setAttribute("Parent",$_REQUEST['level']);
$objectTag->setAttribute("Visibile","1");
$objectTag->setAttribute("type","MAPDRAW_OBJECT");
$graphicTag = $xml->createElement("Graphic");
$graphicTag->setAttribute('AlwaysShowName','1');
$graphicTag->setAttribute('Font',"Calibri");
$graphicTag->setAttribute('Name',strtoupper($_REQUEST["callsign"]));
$graphicTag->setAttribute('TextColor',"0");
$graphicTag->setAttribute('TextPosition',6);
$graphicTag->setAttribute('Version',"1.0");
$graphicTag->setAttribute('Visible',1);
$graphicTag->setAttribute('Size',12);
$layerTag = $xml->createElement("Layer");
$layerTag->setAttribute('ID',$getId);
$graphicPrimTag = $xml->createElement("GraphicPrimitive");
$graphicPrimTag->setAttribute('Type','CircleSector');
$graphicPrimTag->setAttribute('Version','1.0');
$penTag = $xml->createElement('Pen');
$penTag->setAttribute('A',255);
$penTag->setAttribute('B',255);
$penTag->setAttribute('G',255);
$penTag->setAttribute('R',255);
$penTag->setAttribute('Type',0);
$penTag->setAttribute('size',4);
$brushTag = $xml->createElement('Brush');
$brushTag->setAttribute('A',$color[0]);
$brushTag->setAttribute('B',$color[1]);
$brushTag->setAttribute('FillStyle',10);
$brushTag->setAttribute('G',$color[2]);
$brushTag->setAttribute('R',$color[3]);
$circleTag = $xml->createElement('CircleSector');
$circleTag->setAttribute('Radius',500);
$fontTag = $xml->createElement('Font');
$fontTag->setAttribute('Name','Calibri');
$fontTag->setAttribute('size','15');
$coordsTag = $xml->createElement("Coordinates");
$coordsTag->setAttribute("Absolute","1");
$coordsTag->setAttribute('System','WGS84');
$refcoordTag = $xml->createElement("RefCoordinate");
$refcoordTag->setAttribute('Rotation',0);
$refcoordTag->setAttribute('X',$latRad);
$refcoordTag->setAttribute('Y',$longRad);
$refcoordTag->setAttribute('Z','0');
$coordTag = $xml->createElement("Coordinate");
$coordTag->setAttribute('X',$latRad);
$coordTag->setAttribute('Y',$longRad);
$coordTag->setAttribute('Z','0');
$coordTag->setAttribute('index','0');
$accessTag = $xml->createElement("AccessRights");
$accessTag->setAttribute('Editable',0);
$accessTag->setAttribute('Moveable',0);
$accessTag->setAttribute('Selectable',1);
//Append RefCoordinate and Coordinate to Coordinates
$coordsTag->appendChild($refcoordTag);
$coordsTag->appendChild($coordTag);
//append Pen, Brush, CircleSelector and Font to GraphicPrimitive
$graphicPrimTag->appendChild($penTag);
$graphicPrimTag->appendChild($brushTag);
$graphicPrimTag->appendChild($circleTag);
$graphicPrimTag->appendChild($fontTag);
//Append Layer, GraphicPrimitive, Coordinates to Graphic
$graphicTag->appendChild($layerTag);
$graphicTag->appendChild($graphicPrimTag);
$graphicTag->appendChild($coordsTag);
//Append Graphic to Object
$objectTag->appendChild($graphicTag);
$objectTag->appendChild($accessTag);
//Append Object to Objects
$rootTag->appendChild($objectTag);
echo($fileUrl);
$xml->save($fileUrl);
$xml->save("..temp/".$fileName);
exit();
};
I tried running these (first one to save to location that $xml was loaded from i assume? and the second one to a temp folder for javascript - second one can have the declaration).
$xml->saveXML($xml->documentElement);
$xml->save("..temp/".$fileName);
But get this error below
Warning: DOMDocument::save(..temp/bms_overlays.xml) [domdocument.save]: failed to open stream: No such file or directory in D:\Programs\server2go\htdocs\analyst\scripts\createcontent.php on line 152
Any help would be Greatly appreciated as this is the first time i have played with php and xml.
Cheers,
Mitchell

PHP appendChild to XML root

I know this should be simple, but I'm new to PHP and just do not understand the documentation I've come across. I need a simple explanation.
I have an XML document that I would like to add nodes to. I can add nodes to the document, they only appear outside of the root node and cause errors to happen on subsequent attempts.
Here is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
</root>
and here is my PHP:
$playerID = "id_" . $_POST['player'];
//load xml file to edit
$xml = new DOMDocument();
$xml->load('../../saves/playerPositions.xml') or die("Error: Cannot load file.");
//check if the player is already in the database
if(isset($xlm->$playerID)){
echo "Player ID was found.";
}
else{
echo "Player ID was not found.";
//so we want to create a new node with this player information
$playerElement = $xml->createElement($playerID, "");
$playerName = $xml->createElement("name", "John Doe");
//add the name to the playerElement
$playerElement->appendChild($playerName);
//add the playerElement to the document
//THIS IS WHERE THE ERROR OCCURS
$xml->root->appendChild($playerElement);
//save and close the document
$xml->formatOutput = true;
$xml->save("../../saves/playerPositions.xml");
}
echo "done";
If I just use $xml->appendChild() then I can modify the document, but the new text appears outside of <root></root>.
The exact error is:
Notice: Undefined property: DOMDocument::$root
$xml->root isn't the correct way to access root element in this context, since $xml is an instance of DOMDocument (It will work if $xml were SimpleXMLElement instead). You can get root element of a DOMDocument object from documentElement property :
$xml->documentElement->appendChild($playerElement);
eval.in demo 1
Or, more generally, you can get element by name using getElementsByTagName() :
$xml->getElementsByTagName("root")->item(0)->appendChild($playerElement);
eval.in demo 2
Further reading : PHP DOM: How to get child elements by tag name in an elegant manner?
That said, this part of your code is also not correct for the same reason (plus a typo?):
if(isset($xlm->$playerID)){
echo "Player ID was found.";
}
Replace with getElementsByTagName() :
if($xml->getElementsByTagName($playerID)->length > 0){
echo "Player ID was found.";
}
You are trying to handle the dom like a Standar Object, but is not.
To look for elements, you need to use the function getElementsByTagName, and handle the dom like a collection of nodes, like this:
$xml = new DOMDocument();
$xml->loadXML('<?xml version="1.0" encoding="UTF-8"?>
<root>
</root>') or die("Error: Cannot load file.");
$len = $xml->getElementsByTagName('player')->length;
if ( $len > 0 ) {
} else {
$player = $xml->createElement('player', '');
$playerName = $xml->createElement('playerName', "Jhon Doe");
$player->appendChild( $playerName );
$root = $xml->getElementsByTagName('root');
if ( $root->length > 0 ) {
$root[0]->appendChild( $player );
}
$xml->formatOutput = true;
echo $xml->saveXML();
}
This code produces:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<player><playerName>Jhon Doe</playerName></player></root>

How to Enhance This? Get a Part of a Web Page in Another Domain

I have made this:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(
function()
{
$("body").html($("#HomePageTabs_cont_3").html());
}
);
</script>
</head>
<body>
<?php
echo file_get_contents("http://www.bankasya.com.tr/index.jsp");
?>
</body>
</html>
When I check my page with Firebug, It gives countless "missing files" (images, css files, js files, etc.) errors. I want to have just a part of the page not of all. This code does what I want. But I am wondering if there is a better way.
EDIT:
The page does what I need. I do not need all the contents. So iframe is useless to me. I just want the raw data of the div #HomePageTabs_cont_3.
Your best bet is PHP server-side parsing. I have written a small snippet to show you how to do this using DOMDocument (and possibly tidyif your server has it, to barf out all the mal-formed XHTML foos).
Caveat: outputs UTF-8. You can change this in the constructor of DOMDocument
Caveat 2: WILL barf out if its input is neither utf-8 not iso-8859-9. The current page's charset is iso-8859-9 and I see no reason why they would change this.
header("content-type: text/html; charset=utf-8");
$data = file_get_contents("http://www.bankasya.com.tr/index.jsp");
// Clean it up
if (class_exists("tidy")) {
$dataTidy = new tidy();
$dataTidy->parseString($data,
array(
"input-encoding" => "iso-8859-9",
"output-encoding" => "iso-8859-9",
"clean" => 1,
"input-xml" => true,
"output-xml" => true,
"wrap" => 0,
"anchor-as-name" => false
)
);
$dataTidy->cleanRepair();
$data = (string)$dataTidy;
}
else {
$do = true;
while ($do) {
$start = stripos($data,'<script');
$stop = stripos($data,'</script>');
if ((is_numeric($start))&&(is_numeric($stop))) {
$s = substr($data,$start,$stop-$start);
$data = substr($data,0,$start).substr($data,($stop+strlen('</script>')));
} else {
$do = false;
}
}
// nbsp breaks it?
$data = str_replace(" "," ",$data);
// Fixes for any element that requires a self-closing tag
if (preg_match_all("/<(link|img)([^>]+)>/is",$data,$mt,PREG_SET_ORDER)) {
foreach ($mt as $v) {
if (substr($v[2],-1) != "/") {
$data = str_replace($v[0],"<".$v[1].$v[2]."/>",$data);
}
}
}
// Barf out the inline JS
$data = preg_replace("/javascript:[^;]+/is","#",$data);
// Barf out the noscripts
$data = preg_replace("#<noscript>(.+?)</noscript>#is","",$data);
// Muppets. Malformed comment = one more regexp when they could just learn to write proper HTML...
$data = preg_replace("#<!--(.*?)--!?>#is","",$data);
}
$DOM = new \DOMDocument("1.0","utf-8");
$DOM->recover = true;
function error_callback_xmlfunction($errno, $errstr) { throw new Exception($errstr); }
$old = set_error_handler("error_callback_xmlfunction");
// Throw out all the XML namespaces (if any)
$data = preg_replace("#xmlns=[\"\']?([^\"\']+)[\"\']?#is","",(string)$data);
try {
$DOM->loadXML(((substr($data, 0, 5) !== "<?xml") ? '<?xml version="1.0" encoding="utf-8"?>' : "").$data);
} catch (Exception $e) {
$DOM->loadXML(((substr($data, 0, 5) !== "<?xml") ? '<?xml version="1.0" encoding="iso-8859-9"?>' : "").$data);
}
restore_error_handler();
error_reporting(E_ALL);
$DOM->substituteEntities = true;
$xpath = new \DOMXPath($DOM);
echo $DOM->saveXML($xpath->query("//div[#id=\"HomePageTabs_cont_3\"]")->item(0));
In order of appearance:
Fetch the data
If we have tidy, sanitize HTML with it
Create a new DOMDocument and load our document ((string)$dataTidy is a short-hand tidy getter)
Create an XPath request path
Use XPath to request all divs with id set as what we want, get the first item of the collection (->item(0), which will be a DOMElement) and request for the DOM to output its XML content (including the tag itself)
Hope it is what you're looking for... Though you might want to wrap it in a function.
Edit
Forgot to mention: http://rescrape.it/rs.php for the actual script output!
Edit 2
Correction, that site is not W3C-valid, and therefore, you'll either need to tidy it up or apply a set of regular expressions to the input before processing. I'm going to see if I can formulate a set to barf out the inconsistencies.
Edit 3
Added a fix for all those of us who do not have tidy.
Edit 4
Couldn't resist. If you'd actually like the values rather than the table, use this instead of the echo:
$d = new stdClass();
$rows = $xpath->query("//div[#id=\"HomePageTabs_cont_3\"]//tr");
$rc = $rows->length;
for ($i = 1; $i < $rc-1; $i++) {
$cols = $xpath->query($rows->item($i)->getNodePath()."/td");
$d->{$cols->item(0)->textContent} = array(
((float)$cols->item(1)->textContent),
((float)$cols->item(2)->textContent)
);
}
I don't know about you, but for me, data works better than malformed tables.
(Welp, that one took a while to write)
I'd get in touch with the remote site's owner and ask if there was a data feed I could use that would just return the content I wanted.
Sébastien answer is the best solution, but if you want to use jquery you can add Base tag in head section of your site to avoid not found errors on images.
<base href="http://www.bankasya.com.tr/">
Also you will need to change your sources to absolute path.
But use DOMDocument

Fetching image using xpath or some other way

I need to fetch the image from a remote page, i tried xpath but i was told it wont work because img does not have nodevalue
Then i was advised to use getAttribute, but i dont know how to get it working.
Any suggestions?
This is my code
<?php
libxml_use_internal_errors(true);
//Setting content type to xml!
header('Content-type: application/xml');
//POST Field name is bWV0aG9k
$url_prefix = $_GET['bWV0aG9k'];
$url_http_request_encode = strpos($url_prefix, "http://");
//Checking to see if url has a http prefix
if($url_http_request_encode === false){
//does not have, add it!
$fetchable_url_link_consistancy_remote_data = "http://".$url_prefix;
}
else
//has it, do nothing
{
$fetchable_url_link_consistancy_remote_data = $url_prefix;
}
//Creating a new DOM Document on top of pre-existing one
$page = new DOMDocument();
//Loading the requested file
$page->loadHTMLFile($fetchable_url_link_consistancy_remote_data);
//Initliazing xpath
$xpath = new DOMXPath($page);
//Search parameters
//Searching for title attribute
$query = "//title";
//Searching for paragraph attribute
$query1 = "//p";
//Searching for thumbnails
$query2 = "//img";
//Binding the attributes to xpath for later use
$title = $xpath->query($query);
$paragraph = $xpath->query($query1);
$images = $xpath->query($query2);
echo "<remotedata>";
//Echoing the attributes
echo "<title-render>".$title->item(0)->nodeValue."</title-render>";
echo "<paragraph>".$paragraph->item(0)->nodeValue."</paragraph>";
echo "<image_link>".$images->item(0)->nodeValue."</image_link>";
echo "</remotedata>";
?>
you should get source attribute of an image tag.
$images->item(0)->getAttribute('src');
if this is normal xhtml, img has no value, you need the value of img/#src

How do I append XML together in PHP

Whats not known how to do properly is the following...
$attendXml = "";
for ($i=0;$i<count($attendData);$i++) {
$attendXml += assocArrayToXML('row',$attendData[$i]);
}
I have written wrong but I think you see what I am trying to do, the code comes from the following program. Retrieving the organXml works okay, the problem occurs with an array (none associative) containing a number of (associative arrays) that's the problem.
How do I merge the XML of each of the associative arrays into one XML differentiated by 'row'.
function assocArrayToXML($root_element_name,$ar)
{
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}> </{$root_element_name}>");
$f = create_function('$f,$c,$a','
foreach($a as $k=>$v) {
if(is_array($v)) {
$ch=$c->addChild($k);
$f($f,$ch,$v);
} else {
$c->addChild($k,$v);
}
}');
$f($f,$xml,$ar);
return $xml->asXML();
}
// Include Libraries
include('services\OrganisationService.php');
include('services\AttendeeService.php');
// Target Organisation
$organ_id = 1;
// Read Organisation Data
$organServ = new OrganisationService();
$organData = $organServ->getOrganisationByID($organ_id);
$organXml = assocArrayToXML('organisation',$organData);
// Read Attendees Data (For Organisation)
$attendServ = new AttendeeService();
$attendData = $attendServ->getAllActiveAttendeeByOrg($organ_id);
$attendXml = "";
for ($i=0;$i<count($attendData);$i++) {
$attendXml += assocArrayToXML('row',$attendData[$i]);
}
//var_dump($attendData);
header ("Content-Type:text/xml");
echo $attendXml;
?>
You need to separate the creation of a nodes in the tree based on an associative array from the creation of the entire xml document string. I also recommend against using create_function to define a recursive function, and instead consider creating a class for handling the XML rendering.

Categories