How to have proper XML layout using PHP input - php

I know thins is not secure at all, but it is still before the beta stage and I'm just looking for functionality. So, I have a user input area where they put in their information. From there, the information is sent to a PHP file which makes it an XML file from there. The only problem is, there are no tags so I will show you the code used to create the XML file and the XML file too.
HTML
<form action="insertdata.php" method="post">
Data1<input name="data" value="" type="text" placeholder="Data">
Data2 <input name="data2" value="" type="text" placeholder="Data">
<input type="submit" value="Submit">
</form>
PHP
$xml = new DOMDocument("1.0");
$data = $xml ->createElement ("Data");
$datat = $xml -> createTextNode($_POST['data']);
$data = $xml ->appendChild ($datat);
$data1 = $xml -> createElement ("Data1");
$data1t = $xml -> createTextNode ($_POST['data1']);
$data1 = $xml -> appendChild ($data1t);
//echo "<xmp>".$xml -> saveXML (). "</xmp>";
$xml ->save("'".$_POST[data]."'.xml") or die ("error creating file");
So, my problem is not the creation of the XML file, it's that the XML file looks like this:
<?xml version="1.0"?>
Datainput
datainput1
Why isn't the data within the file contained by tags?
Also, how would you be able to do this?

You create the elements, but never used them. The $data and $data1 are NEVER used once created, so all you're doing is appending two textnodes to the root element. You want something more like
$xml = new DOMDocument("1.0");
$data = $xml->createElement('Data'); // Create <Data>
$text = $xml->createTextNode($_POST['data']); // fill in text node
$data->appendChild($text); // put textnode inside <Data>...</Data>
$xml->appendChild($data); // insert <Data> into the XML document.

Related

Adding or Updating XML Node PHP? [duplicate]

I just wanted to ask how I can insert a new node in an XML using PHP. my XML file (questions.xml) is given below
<?xml version="1.0" encoding="UTF-8"?>
<Quiz>
<topic text="Preparation for Exam">
<subtopic text="Science" />
<subtopic text="Maths" />
<subtopic text="english" />
</topic>
</Quiz>
I want to add a new "subtopic" with the "text" attribute, that is "geography". How can I do this using PHP? Thanks in advance though.
well my code is
<?php
$xmldoc = new DOMDocument();
$xmldoc->load('questions.xml');
$root = $xmldoc->firstChild;
$newElement = $xmldoc->createElement('subtopic');
$root->appendChild($newElement);
// $newText = $xmldoc->createTextNode('geology');
// $newElement->appendChild($newText);
$xmldoc->save('questions.xml');
?>
I'd use SimpleXML for this. It would look somehow like this:
// Open and parse the XML file
$xml = simplexml_load_file("questions.xml");
// Create a child in the first topic node
$child = $xml->topic[0]->addChild("subtopic");
// Add the text attribute
$child->addAttribute("text", "geography");
You can either display the new XML code with echo or store it in a file.
// Display the new XML code
echo $xml->asXML();
// Store new XML code in questions.xml
$xml->asXML("questions.xml");
The best and safe way is to load your XML document into a PHP DOMDocument object, and then go to your desired node, add a child, and finally save the new version of the XML into a file.
Take a look at the documentation : DOMDocument
Example of code:
// open and load a XML file
$dom = new DomDocument();
$dom->load('your_file.xml');
// Apply some modification
$specificNode = $dom->getElementsByTagName('node_to_catch');
$newSubTopic = $xmldoc->createElement('subtopic');
$newSubTopicText = $xmldoc->createTextNode('geography');
$newSubTopic->appendChild($newSubTopicText);
$specificNode->appendChild($newSubTopic);
// Save the new version of the file
$dom->save('your_file_v2.xml');
You can use PHP's Simple XML. You have to read the file content, add the node with Simple XML and write the content back.

How to get attributes of XML root element using SimpleXMLElement

I have an XML file with the root element name wwwjob. This root element contains attributes, I need to access the value of the 'method' attribute to be able to update various database entries.
This is a little bit of a learning curve at the moment.
<?xml version="1.0" encoding="iso-8859-1"?>
<wwwjob id="32cca11IACH" method="Delete">
some more xml stuff
</wwwjob>
Ive tried:
<?php $xml = $vacancyXML->wwwjob['method']; ?>
This just gave me 'NULL'.
Ive also tried:
<?php $xml = $vacancyXML->getName(); ?>
This just spits out the name 'wwwjob'.
I need to store the method (Delete/Update/Add) as a variable for use in later parts of the function.
Thanks
When loadinG to simplexml, attributes of the root element became attributes of the simpleXml object. So, you can get it just
$str = '<?xml version="1.0" encoding="iso-8859-1"?>
<wwwjob id="32cca11IACH" method="Delete">
</wwwjob>';
$vacancyXML = simplexml_load_string($str);
echo $vacancyXML['method']; // Delete
demo
You can get the attributes of the root element with SimpleXMLElement::attributes():
$www = new SimpleXMLElement($xml);
echo $www->attributes()->method; // Delete
Demo

How to append XML data without overwriting?

I'm in the process of writing an XML file:
<?php
$xml2 = "currenttest";
$xml = new DOMDocument("1.0");
$root = $xml->createElement ('tv');
$xml->appendChild($root);
$root->appendChild($xml->createTextNode("\n"));
$root->appendChild($xml->createTextNode($xml2));
$root->appendChild($xml->createTextNode("\n"));
$xml->save('epg.xml');
XML:
<?xml version="1.0"?>
<tv>
test
</tv>
If i change the text and again runs the code, the old content is deleted.
And I want the old text to stay.
Let's say this:
<?xml version="1.0"?>
<tv>
currenttest...
newtest...
</tv>
My previous way was to write the XML with:
file_put_contents($file, $xml2, FILE_APPEND | LOCK_EX);
FILE_APPEND | LOCK_EX, its helped me that the previous text would not be erased
I found a solution in another post:
$doc->loadXML(file_get_contents('epg.xml'));
foreach($doc->getElementsByTagName('***') as $node)
{
}
But how can it fit into my code?
You have nothing particular to do, just to reload your xml string and to append a new text node to your root element:
// your previous code (I only changed the variable names and added a default encoding)
$text = "currenttest";
$dom = new DOMDocument("1.0", "UTF-8");
$root = $dom->createElement('tv');
$dom->appendChild($root);
$root->appendChild($dom->createTextNode("\n"));
$root->appendChild($dom->createTextNode($text));
$root->appendChild($dom->createTextNode("\n"));
$xml = $dom->saveXML();
// let's add a new element
$newtext = 'newtext';
$dom = new DOMDocument;
$dom->loadXML($xml);
$root = $dom->documentElement; // conveniant way to target the root element
// but you can also write:
//$root = $dom->getElementsByTagName('tv')->item(0);
$root->appendChild($dom->createTextNode($newtext));
$newxml = $dom->saveXML();
echo $newxml;
demo
About $doc->loadXML(file_get_contents('epg.xml'));, note that you don't need to use file_get_contents since DOMDocument has already two methods:
DOMDocument::loadXML that loads the xml content from a string.
DOMDocument::load that loads the xml content directly from a file.
In addition to DOMNode::appendChild that adds a node to an element after all the children nodes of this element, you have also DOMNode::insertBefore to add a node to an element before the child node of your choice.
I tryed the code on top, 'cause i was overwriting my data, but when I coded in my application, it didn't worked cause I was trying to add the new node data in the loaded xml, you have to create a root to add data inside.
$xml = new DOMDocument("1.0", "UTF-8");
//an tag root must be first thing to add
$root = $xml->createElement('root');
$xml->appendChild($root);
Then, just add the data when you need
$xml = new DOMDocument("1.0", "UTF-8");
$xml->load($sFilepath);
$root = $xml->getElementsByTagName('root')->item(0);
your structure must looks like this:
<xml version="1.0" encoding="UTF-8">
<root>
</root>
The answer on top is totally correct. This answer is only to help if somebody is having trouble to understand.

Modify existing XML file with DomDocument PHP

I have an existing xml file of the following format:
<root>
<word>
<label></label>
<definition></definition>
</word>
...
</root>
I'm taking in text through input boxes for the word and definition on the page and passing it to the php script via GET. The goal for the php script is to take the user input and add an additional word element containing the nested elements label (contains actual word) and definition (contains word definition) to the XML document vocab.xml.
Here is the script:
<?php
$word = $_GET['word'];
$definition = $_GET['definition'];
$dom = new DomDocument();
$dom->load("vocab.xml");
$root = $dom->documentElement;
$node = $dom->createElement("word");
$node2 = $dom->createElement("label", $word);
$node3 = $dom->createElement("definition", $definition);
$node->appendChild($node2);
$node->appendChild($node3);
$root->appendChild($node);
$dom->asXML("vocab.xml");
?>
As it stands now the script appears to execute correctly but checking the XML file reveals that no changes were made.
DOMDocument has no method asXML(). You need to use save():
$dom->save("vocab.xml");

How to improve the following code in PHP

Here is a simple form I am using to send XML data in admin_xml.php
<form name="review" action="admin_xml.php" method="post">
<textarea name="xml" cols="40" rows="10"></textarea>
<input class="submit" type="submit" value="Submit Request">
</form>
Here is the XML which I enter in order to retrieve the data from MySQL Database
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersIds>
<Credentials>
<Username>my_username</Username>
<Password>my_password</Password>
</Credentials>
<Criterions>
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
</Criterions>
</GetOrdersIds>
Here is the php code which extracts the tags from the xml:
<?php
$text_all = "<?xml version=\"1.0\"?>\r\n<GetOrdersIds version=\"1.0\">\r\n<Credentials>\r\n<Username>my_username</Username>\r\n<Password>my_password</Password>\r\n</Credentials>\r\n<Criterions>\r\n<OrderNumber></OrderNumber>\r\n<StartDate>2009-01-01</StartDate>\r\n<EndDate>2009-07-01</EndDate>\r\n</Criterions>\r\n</GetOrdersIds>";
$field = "Criterions";
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
?>
The result from the above php code is:
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
When the script is run, the php code goes through my mysql data, and extracts all orders between the Start Date and the End Date given above.
Is there a better way of improving the following php code, so that it performs the same function:
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
This is the code which searches through the xml data and retrieves all the tags.
UPDATE :
Can anyone list the $result code in SimpleXML?
Some temp vars will help and also make it easier to read.
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
Can be rewritten to.
$tagLen = strlen('<'.$field.'>');
$openTag = strpos($text_all, '<'.$field.'>');
$closeTag = strpos($text_all, '</'.$field.'>', $openTag);
$result = substr($text_all, $openTag + $tagLen, $closeTag - $tagLen - $openTag);
or use SimpleXML
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->asXML();
If you want the individual values use this.
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->OrderNumber;
echo $doc->Criterions->StartDate;
echo $doc->Criterions->EndDate;
if you want the element in XML then use asXML():
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->OrderNumber->asXML();
echo $doc->Criterions->StartDate->asXML();
echo $doc->Criterions->EndDate->asXML();
With SimpleXML:
<?php
$xmlSTR = '<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersIds>
<Credentials>
<Username>my_username</Username>
<Password>my_password</Password>
</Credentials>
<Criterions>
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
</Criterions>
</GetOrdersIds>';
$xml = new SimpleXMLElement($xmlSTR);
echo $xml->Credentials->Username;
//To see the entire structure print_r($xml); as php can access objects as arrays
Have a look at the simplexml module.
Use an XML parser like SimpleXML to extract that data:
$doc = simplexml_load_string($_POST['xml']);
$OrderNumber = $doc->Criterions->OrderNumber;
$StartDate = $doc->Criterions->StartDate;
$EndDate = $doc->Criterions->EndDate;
Assuming your XML string is stored in the variable called $text_all (as you show in your example), this will get you what you want man... :-)
$mysql_stuff = '';
$xml = new SimpleXMLElement($text_all);
foreach($xml->Criterions->children() as $criterion) {
$mysql_stuff .= $criterion->asXML()."\n";
}
echo $mysql_stuff;
$mysql_stuff will now contain:
<OrderNumber/>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
I tested this and it works. I hope this answers your question!

Categories