I have the following code:
include('../scrape/simple_html_dom.php');
$file = "http://www.espn.com/golf/leaderboard?tournamentId=2233";
$html = new simple_html_dom();
$html->load_file($file);
foreach($html->find('table[class="leaderboard-table round-4"]') as $div){
$Rd1 = $div->find('td[class="round2 in post"]');
}
I'm attempting to parse the data from that url and then insert by 'class=full-name" the Round1, Round2, Round3 and Round4 scores.
Hower, I keep getting an error that this is an array to string conversion. Can anyone offer guidance? I can't even isolate the data to insert it into a DB.
It depends what your simple_html_dom() class does but just offhand, it's likely you have to first get the contents of the file and load that string since you don't have direct ownership of the file:
include('../scrape/simple_html_dom.php');
$file = "http://www.espn.com/golf/leaderboard?tournamentId=2233";
$html = new simple_html_dom();
# FETCH THE CONTENTS FIRST
$html = file_get_contents($file);
# THIS MAY BE LOADING A FILE, SO INSTEAD LOAD STRING
# PERHAPS THERE IS A load_string() METHOD?
$html->load_file($html);
/**Continue code...**/
If you need to load from a file, get the contents and temporarily store to a file using file_put_contents($html,'temp.txt'), then use the load_file() method...but it all depends what this class does.
Related
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.
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
Problem
I'm trying to edit HTML/PHP files server side with PHP. With AJAX Post I send three different values to the server:
the url of the page that needs to be edited
the id of the element that needs to be edited
the new content for the element
The PHP file I have now looks like this:
<?php
$data = json_decode(stripslashes($_POST['data']));
$count = 0;
foreach ($data as $i => $array) {
if (!is_array($array) && $count == 0){
$count = 1;
// $array = file url
}
elseif (is_array($array)) {
foreach($array as $i => $content){
// $array[0] = id's
// $array[1] = contents
}
}
}
?>
As you can see I wrapped the variables in an array so it's possible to edit multiple elements at a time.
I've been looking for a solution for hours but can't make up my mind and tell what's the best/possible solution.
Solution
I tried creating a new DOMElement and load in the html, but when dealing with a PHP file, this solution isn't possible since it can't save php files:
$html = new DOMDocument();
$html->loadHTMLFile('file.php');
$html->getElementById('myId')->nodeValue = 'New value';
$html->saveHTMLFile("foo.html");
(From this answer)
Opening a file, writing in it and saving it comes is another way to do this. But I guess I must be using str_replace or preg_replace this way.
$fname = "demo.txt";
$fhandle = fopen($fname,"r");
$content = fread($fhandle,filesize($fname));
$content = str_replace("oldword", "newword", $content);
$fhandle = fopen($fname,"w");
fwrite($fhandle,$content);
fclose($fhandle);
(From this page)
I read everywhere that str_replace and preg_replace are risky 'caus I'm trying to edit all kinds of DOM elements, and not a specific string/element. I guess the code below comes close to what I'm trying to achieve but I can't really trust it..
$replace_with = 'id="myID">' . $replacement_content . '</';
if ($updated = preg_replace('#id="myID">.*?</#Umsi', $replace_with, $file)) {
// write the contents of $file back to index.php, and then refresh the page.
file_put_contents('file.php', $updated);
}
(From this answer)
Question
In short: what is the best solution, or is it even possible to edit HTML elements content in different file types with only an id provided?
Wished steps:
get file from url
find element with id
replace it's content
First of all, you are right in not wanting to use a regex function for HTML parsing. See the answer here.
I'm going to answer this question under the presumption you are committed to the idea of retrieving PHP files server-side before they are interpreted. There is an issue with your approach right now, since you seem to be under the impression that you can retrieve the source PHP file by the URL parameter - but that's the location of the result (interpreted PHP). So be careful your structure does what you want.
I am under the assumption that the PHP files are structured like this:
<?php include_some_header(); ?>
<tag>...</tag>
<!-- some HTML -->
<?php //some code ?>
<tag>...</tag>
<!-- some more HTML -->
<?php //some code ?>
Your problem now is that you cannot use an HTML reader (and writer), since your file is not HTML. My answer is that you should restructure your code, separating templating language from business logic. Get started with some templating language. Afterwards, you'll be able to open the template, without the code, and write back the template using a DOM parser and writer.
Your only alternative in your current setup is to use the replace function as you have found in this answer. It's ugly. It might break. But it's definitely not impossible. Make backups before writing over your own code with your own code.
What's the best way to protect against dynamic file access using URL variables? I'm concatenating two URL variables that will form the filename I want to access which will load XML.
$type = $_REQUEST['type']
//(ie. AB);
$timeframe = $_REQUEST['timeframe']
//(ie. 00.04);
//create XML document object model (DOM)
$main_doc = new DOMDocument();
$s = SITE_DIR."/data/file.".$type.".".$timeframe.".xml";
// example file.AB.00.04.xml)
// will be adding test to see if file exists
$main_doc->load($s);
You should check that the request string does not contain ".." and also doesn't contain "/" (or "\" if you're on windows) so that the path does not point to a directory other than one you are referencing.
Perhaps try this:
$timeframe = str_replace(array('..','/','\'),array('','',''),$timeframe);
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.