I have created a XML file using PHP's simple XML, saved the file. When opening the file in php using fopen and printing the contents. my XML looks like this: (see below)
<?xml version="1.0" encoding="UTF-8"?>
<home><orderList><delivery_cost>0.00</delivery_cost><delivery_surname>TEST</delivery_surname><delivery_postcode>1234</delivery_postcode><status>1</status></orderList></home>
I want the xml file looking all indented and on new lines for each element. Does anybody know how to do this?
Thanks
You can do this using the formatOutput property of DOMDocument.
Save your XML like this instead, presuming your XML is in a variable called $yourXML, and you want to save it to a file at $xmlFilePath:
$dom = new DOMDocument();
$dom->loadXML($yourXML);
$dom->formatOutput = true;
$formattedXML = $dom->saveXML();
$fp = fopen($xmlFilePath,'w+');
fwrite($fp, $formattedXML);
fclose($fp);
Code adapted from here.
This is called "pretty printing" and SimpleXML does not do that. If you search on Stack Overflow and elsewhere on the web you'll find custom solutions that do that.
Pretty printing is good for visulation but I don't recommend saving documents in that format.
If you're still looking for a pretty-printer, you can try SimpleDOM's asPrettyXML()
include 'SimpleDOM.php';
$home = simpledom_load_string('<?xml version="1.0" encoding="UTF-8"?>
<home><orderList><delivery_cost>0.00</delivery_cost><delivery_surname>TEST</delivery_surname><delivery_postcode>1234</delivery_postcode><status>1</status></orderList></home>');
echo $home->asPrettyXML();
echo "\n"; for new line in xml
ob_start(); echo '
' . "\n";?>
Related
I am using SimpleXML to write to my XML file on my Apache Server. Here is my PHP code:
<?php
$xmlFile = 'http://localhost/database.xml';
//$xml = new SimpleXMLElement($xmlFile, NULL, TRUE);
$xml = simplexml_load_file($xmlFile);
$xml->addChild("User", "TestUser2");
file_put_contents($xmlFile, $xml->asXML());
?>
My XML file code:
<Usernames>
<User>TestUser1</User>
</Usernames>
The problem I am having is that SimpleXML WILL NOT write to my XML file. I have tried many different methods ($xml->asXML($xmlFile), DOMDocument ... ->save) and none of them are working. I changed the permissions on my file and STILL I cannot write to it:
I have spent hours today trying to get this to work with no success. If anyone has any type of solution it would be great to hear.
When you write the contents to the file, you should pass a system filepath as the first variable, your $xmlFile variable is a URL. Change this to the local file name and it should save.
Based on your comments, the following should work
<?php
$xmlFile = 'http://localhost/database.xml';
$xml = simplexml_load_file($xmlFile);
$xml->addChild("User", "TestUser2");
file_put_contents('/Applications/MAMP/htdocs/DataBase/database.xml', $xml->asXML());
But, I would double check the $xmlFile URL - from what you have said, your local URL could be http://localhost/DataBase/database.xml - you should check that you can open your XML file in Safari using the $xmlFile URL.
I have been working on a project that displays data in an XML file. (It's kind of like an API). I know how to parse XML with PHP, and how to make an XML file in PHP, but they don't work together. :)
Basically, I have two files: parse.php and xml.php.
xml.php grabs info from a MySQL database, and outputs it as XML.
parse.php loads and parses xml.php and outputs it as HTML.
If I run parse.php, it does not load xml.php. However, if I copy the outputted XML (from xml.php) and save it as a xml.xml file (and change the filename in parse.php to 'xml.xml') it works. I'd really appreciate any help.
Content of parse.php:
<?php
$doc = "xml.php";
$doc = #simplexml_load_file($doc) or die("Server Error: Recipe not found!");
$title = $doc->title;
echo $title
?>
Content of xml.php:
<?php
header("Content-type: text/xml");
$dbc = mysql... //gets data from database
echo "<!DOCTYPE..."; //xml stuff here
echo "<title>" . $dataFromMySQL . "</title>";
?>
The database connection works, and the DOCTYPE in the XML is ok, so that's not the problem.
Again, I only get the problem when I generate XML dynamically using PHP. If it's a .XML file, it works fine.
Can anyone help me?
Thanks.
simplexml_load_file will try to actually load the php contents of the xml.php file. It will not run that file first. You need to do some rewriting or use this ugly solution:
ob_start();
include 'xml.php';
$xml = ob_get_clean();
$doc = simplexml_load_string($xml);
//...
NOTE: I like #lonesomeday's proposed solution better, it will just require more rewriting.
#simplexml_load_file($doc);
That is where your problem is. This does not execute xml.php, but attempts to parse that file -- the PHP code that you've written -- as XML. Obviously (since it isn't XML) this won't work.
You have to find a way of getting the output from executing xml.php into parse.php.
The easy way to do this would be to change all your echo calls into $xml .= calls, and simply include xml.php into parse.php.
// xml.php
$xml = '';
$xml .= "<!DOCTYPE..."; //xml stuff here
$output .= "<title>" . $dataFromMySQL . "</title>";
// parse.php
include('xml.php');
simplexml_load_string($xml);
Note that your problem here shows the foolishness of using the error suppression operator #. If you hadn't used it, PHP would have shown you various errors which would have helped you to realise what the problem was.
Addendum: it occurs to me that the best way actually is to forget about the pointless XML step along the way and just convert the database output into HTML.
If you want to do this without rewriting xml.php, you can get PHP to process the file by accessing via url:
$doc = file_get_contents("http://localhost/xml.php");
You're literally loading the local file. Unless you evaluate it, the code doesn't run, so you'll just get the code itself.
You could use CURL to download xml.php over HTTP, or you could make the XML-generation component of the xml.php a callable function which you simply include and execute.
parse.php:
<?php
include('xml.inc');
$doc = #simplexml_load_string(xml_function()) or die("Error");
echo $doc->title;
xml.php:
<?php
include('xml.inc');
header("Content-type: text/xml");
echo xml_function();
xml.inc:
<?php
function xml_function() {
$dbc = mysql... //gets data from database
$xml = "<!DOCTYPE..."; //xml stuff here
$xml .= "<title>" . $dataFromMySQL . "</title>";
return $xml;
}
But... even that seems silly, honestly, when you could have both output methods connect to the same data and skip a generation/parse step. Simply output HTML/XML conditionally.
I need a way to include an external XML file in PHP which does not use simplexml tags. Furthermore, I'd also need it to integrate with other imported XMLs, hence removing file headers as <?XML version...>
Basically have a PHP class which includes methods to dynamically create XML elements based on user-input. For example, I could create a node called "test", set "id=1" as attribute and add child nodes to it. What I basically need, is a way to extract further XML content from other files and have my PHP script recognize it, hence being able to call methods on this imported code. I tried using php's fopen() function but, although it would print the imported XML to the screen, it would not validate and signal an error as soon as the imported code began. I cannot use simpleXML extension for two main reasons. Firstly, the entire class is written using Pre-PHP5 XML handling, and I cannot re-write the whole thing from scratch as it is part of a team-project, secondly, such class features methods which could not be replicated with simpleXML extension.
This is the XML I generate: <?xml version="1.0"?> <ga><dsa>hea</dsa><sda>eh</sda></ga> <gg><ds>he</ds><sd>eh</sd></gg> And it returns: Illegal Content, Line 3 Column 1, highliting the "<" of the "gg" tag... (Which, by the way, is the part imported from the external file.)
This is a snippet of the code used to print imported XML:
$file = simplexml_load_file($url);
foreach($file as $key => $value) {
echo "<" . $key . ">" . $value . "</" . $key . ">\n";
}
How can this be done?
Additional note: Yes, the server suppors PHP 5 (5.2.6), but the code was written in pre-php5.
Judging from your comments I'd say you get an error because a valid XML document needs a root element. You XML has two: <ga> and <gg>, which means the XML is invalid and cannot be parsed.
You should fix your XML by adding a root element. Then the parsing errors will go away.
Another option would be to load the snippet as a document fragment with DOM:
$brokenXML = <<< XML
<?xml version="1.0"?>
<ga><dsa>hea</dsa><sda>eh</sda></ga>
<gg><ds>he</ds><sd>eh</sd></gg>
XML;
$dom = new DOMDocument;
$fragment = $dom->createDocumentFragment();
$fragment->appendXML(trim(str_replace('<?xml version="1.0"?>', '', $brokenXML)));
echo $dom->saveXml($fragment);
Output:
<ga><dsa>hea</dsa><sda>eh</sda></ga>
<gg><ds>he</ds><sd>eh</sd></gg>
But note that this is still not a complete XML document because it misses a root element.
If you want to import a DOM Tree into another, you can use DOMDocument::importNode. To use that with the fragment above, you would do
$dom2 = new DOMDocument('1.0', 'utf-8');
$dom2->appendChild($dom2->createElement('foo'))
->appendChild($dom2->importNode($fragment, true));
echo $dom2->saveXml();
That would result in
<?xml version="1.0" encoding="utf-8"?>
<foo><ga><dsa>hea</dsa><sda>eh</sda></ga>
<gg><ds>he</ds><sd>eh</sd></gg></foo>
If you have an existing document you want to import to, you would simply do
$dom2 = new DOMDocument;
$dom2->load('existingFile.xml');
$dom2->documentElement->appendChild($dom2->importNode($fragment, true));
This would append the fragment as the last child of the root node. If you want to have it somewhere else on the DOM tree, you would have to traverse the DOM tree with Xpath or getElementsByTagName or getElementsById or the childNodes property on the various nodes and then append to that node instead.
I am trying to find out how this would work
For testing purposes, I have made two websites.
One is calling a REST service from the other
I pull the xml data with file_get_contents
if I echo it, I can see a string off data.
But how can I use simpelxml on it, extract data from the nodes themselves?
If I use simplexml_load_file($url), I get some error saying xml declaration only allowed
at the start off the document?
I have this in my testfile
<?php
$url='http://www.woonbel.nl/gps/setgpsloc';
//not working
$xml =simplexml_load_file($url);
print_r($xml);
//just a string
$xml=file_get_contents($url);
echo "<h3>$xml</h3><br>";
?>
this was the xml I send.
I send this from a class file that I included in the top off my php file
if I am sure the webservice is called, maybe that has someting to do with the declaration error?
header('Content-type: text/xml');
echo "<?xml version=\"1.0\"?>\n";
echo "<response>\n";
echo "\t<status>$status_code</status>\n";
echo "\t<fout>Geen</fout>\n";
echo "</response>";
Thanks, Richard
Sounds like there is a blank line at the top of the file, when it should start with the xml declaration. For example:
<?xml version="1.0" encoding="utf-8"?>
Have you got empty lines before the declaration?
Your REST service should be returning XML contents, something like this:
<?xml version="1.0" encoding="utf-8"?>
<results>
<result>
<value awesome="true">LOLCATS</value>
</result>
</results>
You'd then do something along these lines to consume that REST service on the other site:
$xml = simplexml_load_string(file_get_contents('http://example.com/rest.xml'));
foreach($xml->result as $result) {
$value = $result->value;
$awesome = $result->attributes()->awesome;
// do something here with our values and attributes
}
The PHP docs for SimpleXML contain more complicated/real-world examples.
For your specific XML:
$xml = simplexml_load_string(file_get_contents('http://example.com/rest.xml'));
$status = $xml->status;
$fout = $xml->fout;
The error message clearly states that there is a blank, line or character, at the beginning of the xml-data. That could be file-encoding -issue.
I'm using PHP5 to create XML files. I have code like this:
$doc = new DOMDocument();
...
$xml_content = $doc->saveXML();
The problem is that created XML code starts with a root node like this one:
<?xml version="1.0"?>
But I want it to be like this:
<?xml version="1.0" standalone="yes" ?>
I guess I need to call some function on $doc, but I can't figure out which one?
You want to set
$doc->xmlStandalone = true;
It's not a function of the class, it's a property so it's a little harder to find in the docs. You can read about it here.