trying to edit xml file using php simplexml - php

so I am trying to edit an xml file using php's simplexml extension but I am getting some problems and its
when I tried
$settings = simplexml_load_file("settings.xml");
....
if(isset($aInformation['cName']))
{
$settings->general->communityname = $aInformation['cName'];
$settings->asXML();
}
but I failed with the saving step...
$settings = simplexml_load_file("settings.xml");
$xmlconfigs = new SimpleXMLElement($settings);
....
if(isset($aInformation['cName']))
{
$settings->general->communityname = $aInformation['cName'];
$xmlconfigs->asXML();
}
but I failed too with the error
String couldn't be parsed to XML...
and I had tried searching on those posts before but they are the same as my failed example codes something edit XML with simpleXML and PHP SimpleXML error update xml file

Second one is not possible as SimpleXMLElement can only take a well-formed XML string or the path or URL to an XML document. But you are passing an object of class SimpleXMLElement returned by simplexml_load_file. That is the reason it was throwing error String couldn't be parsed to XML...
In first one the asXML() method accepts an optional filename as parameter that will save the current structure as XML to a file.
If the filename isn't specified, this function returns a string on
success and FALSE on error. If the parameter is specified, it
returns TRUE if the file was written successfully and FALSE
otherwise.
So once you have updated your XML with the hints, just save it back to file.
$settings = simplexml_load_file("settings.xml");
....
if(isset($aInformation['cName']))
{
$settings->general->communityname = $aInformation['cName'];
// Saving the whole modified XML to a new filename
$settings->asXml('updated_settings.xml');
// Save only the modified node
$settings->general->communityname->asXml('settings.xml');
}

Related

Laravel 6 - Phpspreadsheet reading file excel

i'm trying to read excel file like this:
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $spreadsheet->load(public_path("dispoP.xlsx"));
But i get this error:
Argument 1 passed to PhpOffice\PhpSpreadsheet\Reader\Xlsx\Styles::__construct() must be an instance of SimpleXMLElement, bool given, called in /Applications/XAMPP/xamppfiles/htdocs/daniele_ecommerce/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php on line 567
Version phpspreadsheet
"phpoffice/phpspreadsheet": "^1.9",
PHP Version
7.3.24
I saw in library package that this return "false" when instead should be instance SimpleXMLElement ?
$xmlStyles = simplexml_load_string(
$this->securityScanner->scan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
'SimpleXMLElement',
Settings::getLibXmlLoaderOptions()
);
thank you! i lost my sunday with this error :)
There is a slight error in the call you mention, but I don't think it's that:
$this->securityScanner->scan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
should be
$this->securityScanner->scan($this->getFromZipArchive($zip, "{$dir}/{$xpath['Target']}")),
The problem has to be indeed where you say.
The simplest thing to do would be to dump the argument to simplexml_load_string() or, possibly, the whole kerfuffle, mainly $dir/$xpath[Target]. You can open the XLSX file as a Zip (just change the extension to .zip) and verify whether the XML file inside is intact and valid.
If it is, this means that the "security Scanner" somehow renders it into something that simplexml_load_string() does not parse - maybe an empty string.

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.

provide latest xml file php

maybe someone can help me, i provide xml files witch are generated from a PHP DB query and each xml file has a unique name. Now i want to prepare a function like "get the latest xml file" but I don't know whats the best way!
$xml = simplexml_load_file('test.xml');
I found this function but there i have to know the exact name!
or ist something like this possible:
$xml = simplexml_load_file('test.php');
and in the test.php i have a function to get the last name, but how to i provide the xml data?
Some keywords how i can find a solution in google would be very helpful!
The first parameter to that function is a string of the filename. The file should be the XML file to load, so you cant use another php file.
http://php.net/manual/en/function.simplexml-load-file.php
So you need to get the filename as a string first by using a variable. You should be able to copy the code in your test.php file, then save the filename instead of echoing it out. Then you use that variable when loading the xml file.
e.g.
function get_latest_filename()
{
//contents of your test.php file should set this variable
$latest_filename = 'the_latest_file.xml';
return $latest_filename;
}
$latest = get_latest_filename();
$xml = simplexml_load_file($latest);
here the finish solution that worked for me
i protected the directory with .htaccess and inside i store all my generated xml files and also the getLastXml.php file!
the getLastXml.php
function get_last_file() {
$lastFileTime = 0;
foreach (glob("*.xml") as $filename) {
if ($lastFileTime<filemtime($filename))
{
$lastFileTime = filemtime($filename);
$lastFileName = $filename;
}
}
return $lastFileName;
}
$lastXmlFile = get_last_file();
header ("Content-Type:text/xml");
echo file_get_contents($lastXmlFile);
the functions get_last_file() returns the name of the latest created xml file and
header ("Content-Type:text/xml");
displays xml in the php file
echo file_get_contents($lastXmlFile);
loads the content of the xml file and display it
simplexml_load_file("http://username:passwort#urlToTheDirectory/getLastXml.php");
loads the xml data with

Deleting XML node with PHP

I'm trying to simply save an XML file from the web locally (this part works fine) and then delete a node of the XML and resave it. However, the local xml file ends up blank when I do the following:
$xml = file_get_contents($xmlurl);
file_put_contents('187file.xml', $xml);
$rep187 = simplexml_load_file('187file.xml');
unset($rep187->ComparableSalesReport->ComparableSales->ComparableSale);
file_put_contents('187file.xml', $rep187);
file_put_contents does not accept an object as the second argument (it only accepts a string, an array or a stream resource).
You can pass a string instead by using SimpleXMLElement::asXML on your $rep187 document, like so:
$xml = file_get_contents($xmlurl);
file_put_contents('187file.xml', $xml);
$rep187 = simplexml_load_file('187file.xml');
unset($rep187->ComparableSalesReport->ComparableSales->ComparableSale);
file_put_contents('187file.xml', $rep187->asXML());

How do I parse an external XML file (returned from a POST) with php?

I have a simple code written (based on some tutorials found around the internet) to parse and display an XML file. However, I only know how to reference an XML file stored on my server and I would like to be able to use an XML file that is being returned to me from a POST.
Right now my code looks like this:
if( ! $xml = simplexml_load_file('test.xml') )
{
echo 'unable to load XML file';
}
else
{
foreach( $xml as $event)
{
echo 'Title: ';
echo "$event->title<br />";
echo 'Description: '.$event->info.'<br />';
echo '<br />';
}
}
Is there some way I can replace the simpleXML_load_file function with one that will allow me to point to the POST URL that returns the XML file?
Use simplexml_load_string instead of loadfile:
simplexml_load_string($_POST['a']);
If you get the url to the file in the POST you can propably use the simplexml_load_file function with the url, but if that doesn't work you can use the file_get_contents in combination with the simplexml_load_string:
//say $_POST['a'] == 'http://example.com/test.xml';
simplexml_load_file($_POST['a']); // <-- propably works
simplexml_load_string(file_get_contents($_POST['a'])); //<-- defenitly works (propaly what happens internally)
also getting contents of external files could be prohibited by running PHP in safe mode.
If you are receiving a file that's been uploaded by the user, you can find it (the file) looking at the content of the $_FILES superglobal variable -- and you can read more about files uploads here (for instance, don't forget to call move_uploaded_file if you don't want the file to be deleted at the end of the request).
Then, you can work with this file the same way you already do with not-uploaded files.
If you are receiving an XML string, you can use simplexml_load_string on it.
And if you are only receiving the URL to a remote XML content, you have to :
download the file to your server
and, then, parse its content.
This can be done using simplexml_load_file, passing the URL as a parameter, if your server is properly configured (i.e. if allow_url_fopen is enabled).
Else, the download will have to be done using curl -- see curl_exec for a very basic example, and curl_setopt for the options you can use (you'll especially want to use CURLOPT_RETURNTRANSFER, to get the XML data as a string you can pass to simplexml_load_string).
From http://www.developershome.com/wap/wapUpload/wap_upload.asp?page=php4:
If you do not want to save the
uploaded file directly but to process
it, the PHP functions
file_get_contents() and fread() can
help you. The file_get_contents()
function returns a string that
contains all data of the uploaded
file:
if (is_uploaded_file($_FILES['myFile']['tmp_name']))
$fileData = file_get_contents($_FILES['myFile']['tmp_name']);
That will give you a handle on the raw text within that file. From there you will need to parse through the XML. Hope that helps!
Check out simplexml_load_string. You can then use cURL to do the post and fetch the result. An example:
<?php
$xml = simplexml_load_string($string_fetched_with_curl);
?>

Categories