This question already has an answer here:
update/append data to xml file using php
(1 answer)
Closed 8 years ago.
I am currently using php 5.5.15
This is the code I use to write a simple xml file called comment.xml using DOM. Now the structure of the file as illustrated below is what I require. What I would appreciate is code sample which will allows me to read all users and comments and out put them say to html. and also code sample to append to the file below.
any help much appreciated.
/*** a new dom object ***/
$dom = new domDocument;
/*** make the output tidy ***/
$dom->formatOutput = true;
/*** create the root element ***/
$root = $dom->appendChild($dom->createElement( "comments" ));
/*** create the simple xml element ***/
$sxe = simplexml_import_dom( $dom );
/*** add a user element ***/
$sxe->addChild("user", $User_Name);
/*** add a comment element ***/
$sxe->addChild("comment", $Comment);
$dom->save('comment.xml');
The output for the above code is:
<?xml version="1.0"?>
<comments>
<user>Joe Blogs</user>
<comment>This is a comment</comment>
</comments>
Something like this would suffice
$xmlStr = '<container><comments><user>Joe Blogs</user><comment>This is a comment</comment></comments><comments><user>John Doe</user><comment>This is another comment</comment></comments></container>';
$dom = new DOMDocument;
$dom->loadXML($xmlStr);
if (!$dom) {
echo 'Error while parsing the document';
exit;
}
$xmlObj = simplexml_import_dom($dom);
foreach($xmlObj->comments as $child) {
echo 'user: '.$child->user.'<br>';
echo 'comment: '.$child->comment.'<br>';
echo '-----------------<br>';
}
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
I'm trying to write a droid app that sends and receives XML between the app and a web service. When I try to run the following code
$dom = new domDocument;
$dom = simplexml_load_file('php://input');
$xml = simplexml_import_dom($dom);
$messages = Messages::find_by_sql("SELECT * FROM messages WHERE reciever = '$xml->userName'");
$xmlString = "";
if($messages)
{
foreach($messages as $message)
{
$ts = strtotime($message->ts);
$xmlString=$xmlString."<Message><sender>".$message->sender."</sender><reciever>".$message->reciever."</reciever><timestamp>"."123"."</timestamp><text>".$message->text."</text></Message>";
}
}
else
{
//do something
}
$xmlReturn = new DOMDocument('1.0', 'UTF-8');
$xmlReturn->loadXML($xmlString);
echo($xmlReturn->saveXML());
?>
I get a Warning Extra content at the end of the document.
The error comes from this line: $xmlReturn->loadXML($xmlString);
I'm not 100% sure that you can create an xml document by loading a string, but I've seen similar things done and if you look here you can see what it ouputs, which looks like valid XML to me.
An XML document can have only one root element. You are stringing together multiple <message>…</message> combinations here, so a root element encapsulating those is missing.
I have a short script that utilizes the XML_Query2XML PEAR package. It pulls data from a SQL database and outputs to the browser. The XML that appears in the browser is exactly what I want to be saved to a file, but any attempts to use ob_get_contents or any of the other methods I'm familiar with result in a blank output file. The code is as follows:
<?php
set_include_path('/Library/WebServer/Documents/PEAR/');
include 'XML/Query2XML.php';
include 'MDB2.php';
try {
// initialize Query2XML object
$q2x = XML_Query2XML::factory(MDB2::factory('mysql://root:pass#site.com/site'));
$sql = "SELECT * FROM Products";
$xml = $q2x->getFlatXML($sql);
header('Content-Type: text/xml');
$xml->formatOutput = true;
echo $xml->saveXML();
} catch (Exception $e) {
echo $e->getMessage();
}
?>
I'm wondering what the general procedure is for saving files with this plugin and output type (XML). Any help is greatly appreciated.
The $xml variable is a DOMDocument object, which means you can use its methods to save it into a file, e.g. save:
$xml->save('foo.xml');
This question already has answers here:
How to make xml file from php and mysql
(3 answers)
Closed 10 years ago.
I'm using this code to create an XML file (not filed) from a PHP one. Here is the code:
<?php
include_once ('conf.php');
$conn = mysql_connect($host, $user, $password);
if (!$conn) {
die('No hay conexion a la BBDD');
}
$bd = mysql_select_db($name, $conn);
if (!$bd) {
die ('Error en la BBDD');
}
$query = "select * from usuarios where activo = 0 order by puntuacion desc limit 0, 10";
$res = mysql_query($query, $conn);
$salida = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>'."\n";
$salida .= '<score>'."\n";
$i = 1;
while ($row = mysql_fetch_array($res))
{
$salida.= '<posicion num="' . $i . '">'."\n";
$salida .= '<id>'.$row['id'].'</id>'."\n";
$salida .= '<puntuacion>'.$row['puntuacion'].'</puntuacion>'."\n";
$salida .= '</posicion>'."\n";
$i++;
}
$salida .= '</score>';
mysql_free_result($res);
mysql_close($conn);
echo $salida;
?>
When I call this file I obtain (using Chrome Inspector) the XML file embeded in a HTML file with its html, head and body tags. I want this php file to get readed by an ajax's get function.
Any ideas about what is wrong?
Add a header specifying that you're outputting XML. header('Content-Type: text/xml') right before you echo.
Read the PHP manual about XML Manipulation.
You will find juicy tools there to fetch, manipulate and create XML documents.
Also, before making any output, add a line header ("Content-type: text/xml"); to your script, to specify for the client entity, that you are going to send XML and it should be parsed as XML. header — Send a raw HTTP header