Formatting output to file with PHP DOMDocument - php

So I wrote this script that looks for certain nodes in an XML file, deletes it, and puts a new node in it's place... however, the new node is showing up like so:
<PrintQuestion id="17767" type="pickOne">
<Standards><Standard value="CA.MATH-6-6-20" state="CA" grade="3" subject="MATH"/></Standards><References>
<PassageRef id="1892"/>
</References>
I've attempted to use the $xml->formatOutput = true; but that has done nothing. I'm loading the dom object from an XML file and saving it back to the same file upon completion.

When you want to use
$xml->formatOutput = TRUE;
you also have to set
$xml->preserveWhiteSpace = FALSE;
You wrote preserveWhitespace (mind the 2nd s). Properties are case-sensitive in PHP.
See difference on codepad

Related

Parse XML file within laravel

I want to select a XML file from my computer to be parsed. The form works and I can use the Input::file('file'); function. However I want to parse this document by favour with uploading it only as temporary file. When I want to parse it I get errors like: "unable to parse from string". It seems that parser can't find the file. I tried two parsers: SimpleXML and XMLParser(from orchestral).
public function uploadFile(Request $ file){
$data =Input::file('file');
$informationdata = array('file' => $data);
$rules = array(
'file' => 'required|mimes:xml|Max:10000000',
);
$validator= Validator::make($informationdata, $rules);
if($validator->fails()){
echo 'the file has not the correct extension';
} else{
XmlParser::load($data->getRealPath());
}
I also tried to parse it after storing the file.
private function store($data){
$destinationPath = public_path('uploads\\');
$fileName = $data->getClientOriginalName();
$data->move($destinationPath,$fileName);
$xml = simplexml_load_file($destinationPath.$fileName);
}
Thanks in advance for helping.
When you say "parse" what do you mean? Find nodes? Delete nodes? Add nodes? Or only read nodes?
Because you can find and read with the SimpleXMLElement class but if you want to add or delete I suggest you to use DomDocument instead.
Using SimpleXMLElement, the construct would be:
$xml = new SimpleXMLElement($destinationPath.$fileName, null, true);
While the DomDocument would be:
$xml = new DomDocument('1.0', 'utf-8'); // Or the right version and encoding of your xml file
$xml->load($destinationPath.$fileName);
After you create the object, you cand handle all the document.
It is unknown, whether you want to validate some exiting xml-file on your computer or want to implement the ability for users to upload any xml file and write some logic to cope this task. However, this is not the point.
I would recommend you to use the built-in to PHP core simplexml_load_file() function which has helped me with the project. Because you will never get Laravel to parse xml into some decent understendable array or object to work with through Request $file injections etc. This is good to work with html-forms or json, not with xml or other formats.
That's why you should work with object which will be the result of (for example) such code:
$xml_object = simplexml_load_file($request->file('action')->getRealPath());
And then you'll need to verify every xml node and field by yourself, writing some logic as you lose the possibility of using built-in to Laravel Illuminate\Http\Request validate() method.

Appending an XML File Using PHP

I have a PHP file which contains a HTML form. When the user enters data into the form, it carries out error checking and if everything is in order the data entered is written to an XML file in a specific order. This part works perfectly. My problem is when the user fills in this form again, I need the new data to append to the XML file (not overwrite it). Currently, it simply over writes the data, could someone help me out on how I would do this? I tried watching tutorials but I am very new to XML and found them confusing. My XML file is as follows;
<?php
function createFile($xml_file)
{
$FileMessageID = $_POST['messageid'];
$FileCreation = $_POST['filedatetime'];
$FileTransactions = $_POST['filetransactions'];
$FileControlSum = $_POST['filecontrolsum'];
$CID = $_POST['CID'];
// create new dom document
$xml = new DOMDocument();
// these lines would create a nicely indented XML file
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
// create a root element, and add it to DOM
addRoot($xml);
// add more elements to xml file
$CustomerDDInfo = $xml->createElement("CstmrDrctDbtInitn");
// add this element to the root
$xml->documentElement->appendChild($CustomerDDInfo);
// create elements
$GroupHeader = $xml->createElement("GrpHdr");
$InitiatingParty = $xml->createElement("InitgPty");
$IdentificationHeading = $xml->createElement("Id");
$PrivateIdentification = $xml->createElement("PrvtId");
$Other = $xml->createElement("Othr");
// append these elements to friend
$CustomerDDInfo->appendChild($GroupHeader);
$GroupHeader->appendChild($xml->createElement('MsgID', $_POST['messageid']));
$GroupHeader->appendChild($xml->createElement('CreDtTm', $_POST['filedatetime']));
$GroupHeader->appendChild($xml->createElement('NbOfTxs', $_POST['filetransactions']));
$GroupHeader->appendChild($xml->createElement('CtrlSum', $_POST['filecontrolsum']));
$GroupHeader->appendChild($InitiatingParty);
$InitiatingParty->appendChild($IdentificationHeading);
$IdentificationHeading->appendChild($PrivateIdentification);
$PrivateIdentification->appendChild($Other);
$Other->appendChild($xml->createElement('Id', $_POST['CID']));
$CustomerDDInfo->appendChild($PaymentInformation);
// save dom document to an xml file
$xml->save($xml_file);
}
function addRoot(&$xml)
{
$xml->appendChild($xml->createElement("entry"));
}
// call xml function
createFile('SEPA.xml');
//Redirect to Thank You Page
header ('Location: thankyou.php');
?>
load the existing XML document (if there is one)
add a child at the correct level with the information you would like to append
An XML is not like a text file, where you just put other data at the bottom of it. In XML you have to put the extra information inside a node somewhere inside the existing XML.
<exampleXML>
<item>
<name></name>
<number></number>
<date></date>
</item>
</exampleXML>
When another item to the XML you should load the XML, take the 'exampleXML' node and append a child to it.
Result:
<exampleXML>
<item>
<name></name>
<number></number>
<date></date>
</item>
<item>
<name></name>
<number></number>
<date></date>
</item>
</exampleXML>
I don't often work with XML DOM in PHP so I can't really provide you any code.
Look at http://www.php.net/manual/en/class.domdocument.php for the correct functions.

XML saving doesn't work on filesystem

I tried many ways to save xml file on my filesystem, but it doesn't work. I don't know what can I do...
I only want to read an xml file, then modify the value of a node, and then save this file... But nothing happened. In PHP I don't know what the problem. In Java okay... but I need to do in PHP.
XML file:
<?xml version="1.0"?>
<node>
<pass>test</pass>
</node>
public static function saveToXML()
{
$xml = simplexml_load_file(dirname(__FILE__).'/../../../../sms_data.xml');
$xml->pass = "000";
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
echo $dom->saveXML();
}
The $xml is contains the modified values. It is good, but the save function doesn't wanna work!
I tried this too: echo $dom->save('text.xml'); But nothing. It doesn't create the text.xml file... I don't know... I have been searching for the solutions on google for one day. But I don't know what the hell is going to always wrong. I didnt get nothing. The server log is empty about it...
I am so sorry to ask this. But I don't understand this code why doesn't work... why doesn't save the modification on filesystem level!
Check if the directory exists and is writable.

PHP Cross Site XML [duplicate]

This question already has answers here:
PHP HttpRequest
(3 answers)
Closed 9 years ago.
I have this in file called abc.php, and this will return a valid xml document, instead of showing -string- labels at the end and beggining
header('Content-type: application/xml');
$xml = file_get_contents("http://www.xxx.asmx/test?id=1"); //External web service
$xmlstr = simplexml_load_string($xml);
echo $xmlstr;
I want to use the valid xml data of abc.php, extract certain data, store it in my db, and check the output of the other server periodically, I've tried this:
ob_start();
include 'abc.php';
$result = ob_get_clean()
as well as this:
$xml = file_get_contents("abc.php");
$xmlstr = simplexml_load_string($xml);
without success, any advice?
Make sure you output the MIME Type as well, or else the server will feed text/html to it and it will be all wrong. Put this function
header("Content-type: application/xml");
in abc.php so the client will recognize it as XML.
file_get_contents("abc.php") will return you the contents of the file "abc.php"; it will not execute that PHP code. The include with output buffering trick ought to do roughly the right thing, but I'm not sure why you'd ever want to do it that way, so it's not worth working out why that's failing.
If you can access the code in abc.php, then simply make it into a PHP function, which returns the processed XML:
function get_the_actual_xml()
{
$xml = file_get_contents("http://www.xxx.asmx/test?id=1"); // External web service
$xml_obj = simplexml_load_string($xml); // Load into SimpleXML object
return (string)$xml_obj; // Convert contents back to a string
}
If for some reason your two PHP files need to be on different servers, you will need to reference the URL to abc.php, not just where it is on disk. That way, the PHP code will be executed, and what you'll get back is the result of that echo statement. If your server has the allow_url_fopen setting enabled, this is as simple as $remotely_processed_content = file_get_contents('http://sanjosecostarica.org/test/abc.php')
at the end I couln't get the results of "abc.php" but only the content, I try a different approach successfully:
$xml = file_get_contents("http://www.xxx.asmx/test?id=1"); //External web service
$xmlstr = simplexml_load_string($xml);
$xmlok = <<<XML
$xmlstr
XML;
$xml = simplexml_load_string($xmlok);

Can I get an XML files structure without looking up the element names myself?

Using PHP, I would like to be able to open an XML file and get its structure without having to know any about the structure already. Is this possible?
I've been using XMLReader up until now but I'm parsing a wide variety of structures so it takes a while to go through each file manually and identify the structure.
I would only need to open the first parent node as every node after that would be the same.
e.g.
<name>
<first></first>
<second></second>
</name>
I would like to be able to identify this structure without having to manually look at the file first.
Happy to use other libraries than XMLReader but would need to stick with PHP.
Thanks!
DOMDocument should be able to do it.
$dom = new DOMDocument();
$dom->loadHTML($xml_data);
/* #var $names DOMNodeList */
$names = $dom->getElementsByTagName('name');
for($i=0;$i<$names->length;$i++){
$node = $names->item($i);
if($node->nodeName=='first'){
$first_name = $node->nodeValue; // store this
}elseif($node->nodeName=='second'){
$second_name = $node->nodeValue; // store this
}
}
Make sure that they are valid XML files.

Categories