Jump to content

Submitting from a PHP Form to XML document


kvnmck18

Recommended Posts

& = & < = < > = > '= '" = "...with that said... on a form that sumbits through php to XML is it possible to automatically convert the: &, <, >, ', "? Well, I'm sure it's possible... does anyone know how to?<input value="<:3 )~~~ "A 'mouse'", he said." />

Link to comment
Share on other sites

  • 3 weeks later...

Where can I use this in a form to XML? I think it needs to be added to the:<?php $xml_file = "xml.xml"; $xslt_file = "xsl.xsl"; $xp = xslt_create() or die("Could not create XSLT processor"); if($result = xslt_process($xp, $xml_file, $xslt_file)) { echo $result; } else { echo "An error occurred: " . xslt_error($xp) . "(error code " . xslt_errno($xp) . ")"; } xslt_free($xp); ?> ...and somewhere in the process. Just not sure. :\!

<?php$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);echo $new; // <a href='test'>Test</a>?>

Form.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" ><html xmlns="http://www.w3.org/1999/xhtml"><body><form action="process.php" method="post"><table cellspacing="0" class="ttop"><tr><td id="left"> Category : </td><td><select id="cat" name="cat">  <option>--CHOOSE--</option>  <option id="cat" name="cat" value="one">One</option>  <option id="cat" name="cat" value="two">Two</option></select></td></tr><tr><td id="left"> Subject :</td><td><input type="text" id="subj" name="subj" /></td></tr><tr><td id="left">Other: </td><td><input type="text" id="other" name="other" /></td></tr><tr><td id="left">Add or Delete:</td><td><select name="action"><option value="ins">--CHOOSE--</option><option value="ins">Add</option><option value="del">Delete</option></select></td></tr><tr><td id="left2"> Make Sure All <br />Information Is Correct </td><td id="leftsub"><input type="submit" id="sub" value="SUBMIT" /></td></tr></table></form><br /><?php $xml_file = "xml.xml"; $xslt_file = "xsl.xsl"; $xp = xslt_create() or die("Could not create XSLT processor"); if($result = xslt_process($xp, $xml_file, $xslt_file)) {	  echo $result; } else {	  echo "An error occurred: " . xslt_error($xp) . "(error code " . xslt_errno($xp) . ")"; } xslt_free($xp); ?> </body></html>

Process.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body><?$whatever = Array();function start_element($parser, $name, $attrs){	global $whatever;	if($name == "arg"){		array_push($whatever, $attrs);	}}function end_element ($parser, $name){}$whateverXML_string = file_get_contents("xml.xml");$parser = xml_parser_create();xml_set_element_handler($parser, "start_element", "end_element");xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);xml_parse($parser, $whateverXML_string) or die("Error parsing XML document.");print "<br />";if($_POST['action'] == "ins"){	array_push($whatever, Array(				"cat" => $_POST['cat'],				"subj" => $_POST['subj'],				"other" => $_POST['other'],		$whatever_final = $whatever;}else if($_POST['action'] == "del"){	$whatever_final = Array();	foreach($whatever as $arg){		if($arg['id'] != $_POST['id']){			array_push($whatever_final, $arg);		}	}}$write_string = "<whatever>";foreach($whatever_final as $arg){	$write_string .= "<arg cat=\"$arg[cat]\" subj=\"$arg[subj]\" other=\"$arg[other]\" />";}$write_string .= "</whatever>";$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";print "<br />";print "<a href=\"form.php\" title=\"return\">Return</a>";?></body></html>

....something like this?:

$write_string .= "</faq>";$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";

to

$write_string .= "</whatever>";htmlspecialchars($write_string);$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";

...but wouldn't that make the <whatever /> be changed too?

Link to comment
Share on other sites

That's one big bunch of messy-and-unfamiliar-to-me code.Your last code:

$write_string .= "</whatever>";htmlspecialchars($write_string);$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";

Should only write the litteral string

</whatever>

in the end of the xml.xml file, making it a non-well formed XML document.By the way, following the example from the reference, I think this code should look more like:

$input_string = "</whatever>";$write_string = htmlspecialchars($input_string);$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";

Link to comment
Share on other sites

That would create the </whatever> just to be </whatever>But I want this to make:

<whatever><arg cat="One" subj="My friends & Me" other="I don't know what to say here" /></whatever>

to:

<whatever><arg cat="One" subj="My friends & Me" other="I don't know what to say here" /></whatever>

using the htmlspecialchars() function.

Link to comment
Share on other sites

Oh... that... I'm starting to see why you needed the complex PHP above :) .You first need to select the proper node with the XML reader and then replace that node with a new one with the XML writer. The new string will of course be htmlspecialchars($the-old-node).How exactly to do that is another question though. I'm still exploring PHP's XML functions myself.

Link to comment
Share on other sites

How exactly to do that is another question though.
That's my question too hahaI think it's either the $whatever_final, or $arg that needs the htmlspecialchars()
Link to comment
Share on other sites

I still can't figure this out. I think I will start crying until it is solved....or at least have a headache.

Link to comment
Share on other sites

Hey, I just got a brilliant idea!In order to edit an XML document, you could generate the XML data that you'll be adding, and use XSLT in order to place that data in the right spot. The output itself should completely replace the old XML file.With PHP5, it's easier, because you just have to use the transformToURI() function, but in PHP4 you have to first generate the output, get the old file's name, delete that file and create a new file with the output as it's content.An XSLT that may do a good job is something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:param name="input"/><xsl:template match="/*"><xsl:element name="{name()}"><xsl:copy-of select="*" /><xsl:copy-of select="$input"/></xsl:element></xsl:template></xsl:stylesheet>

where the parameter $input contains the... input of course... that is passed to it.Using this particular stylesheet will place the whole input just before the closing tag of the root element.Editing existing entries might involve generating a new "input" from the old XML file that will have the desired data, a second transformation with the XML without that data, and a third transformation to use second output as it's input and pass the first output as a parameter for the same transformation above.

Link to comment
Share on other sites

Sorry...what? You lost me, I don't follow what you are saying.and... how does that do:& = &< = <> = >' = ' " = "

???????????????????????

...errr! It changed my characters for them~

Link to comment
Share on other sites

Sorry. I guess I got over exited when thinking about this. Consider the following XML as the value of a parameter for the stylesheet above:

<name>	<first>Bill</first>	<last>Gates</last>	<notes>click <a href="here.html">here</a></notes></name>

and consider this XML as the input for that very same stylesheet:

<note>	<to>Tove</to>	<from>Jani</from>	<heading>Reminder</heading>	<body>Don't forget me this weekend!</body></note>

If what I think is right, the result of such transformation shuold be:

<note>	<to>Tove</to>	<from>Jani</from>	<heading>Reminder</heading>	<body>Don't forget me this weekend!</body>	<name>		<first>Bill</first>		<last>Gates</last>		<notes>click <a href="here.html">here</a></notes>	</name></note>

Saving this output as a new file or should I say completely owerwritting the previous one would be like an euivalent to editing the XML.

Link to comment
Share on other sites

What if I just... added htmlspecialchars() to the actual form (Form.php) to change the &, ", ', ?,<,>...but then I have the problem once I add another the previous characters go back to be invalid (An error occurred: XML parser error 4: not well-formed)....because the "w+" in the php handeling, rewriting the whole xml and not reading & as & but making & = &...Resulting in the error. And if I add the htmlspecialchars to the php it would make the whole XML in the specialcharsERR there must be a solutionI think if I make the args process as specialchar it might work but that might do the same thing as mentioned above (once another one added it goes back to the "&'s and ects")Just the "$arg[cat]" "$arg[subj]" "$arg[other]" need the htmlspecialchar().... so whenever cat is equal to a value, use htmlspecialchar... same when dealing with subj="something" other="something".(again) Form.php:

<?$whatever = Array();function start_element($parser, $name, $attrs){	global $whatever;	if($name == "arg"){		array_push($whatever, $attrs);	}}function end_element ($parser, $name){}$whateverXML_string = file_get_contents("xml.xml");$parser = xml_parser_create();xml_set_element_handler($parser, "start_element", "end_element");xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);xml_parse($parser, $whateverXML_string) or die("Error parsing XML document.");print "<br />";if($_POST['action'] == "ins"){	array_push($whatever, Array(				"cat" => $_POST['cat'],				"subj" => $_POST['subj'],				"other" => $_POST['other'],		$whatever_final = $whatever;}else if($_POST['action'] == "del"){	$whatever_final = Array();	foreach($whatever as $arg){		if($arg['id'] != $_POST['id']){			array_push($whatever_final, $arg);		}	}}$write_string = "<whatever>";foreach($whatever_final as $arg){	$write_string .= "<arg cat=\"$arg[cat]\" subj=\"$arg[subj]\" other=\"$arg[other]\" />";}$write_string .= "</whatever>";$fp = fopen("xml.xml", "w+");fwrite($fp, $write_string) or die("Error writing to file");fclose($fp);print "You did it, way to go!!!";print "<br />";print "<a href=\"form.php\" title=\"return\">Return</a>";?>

Link to comment
Share on other sites

Wait I'm thinking.... what if....$fp = fopen("xml.xml", "w+"); was $fp = fopen("xml.xml", "r+"); and the xml.xml was called in another xml (called realxml.xml).xml.xml contains:

<arg cat="One" subj=" asdfsd" other="sf  & sd" /><arg cat="Two" subj="sdaf asdfsd" other="Isdfsdf sdsdf sf sd" /><arg cat="Three" subj="sddfsr4d" other="Isgfsdt56sf sd" />

realxml.xml contains:

<whatever>(call xml.xml)</whatever>

So give you:

<whatever><arg cat="One" subj=" asdfsd" other="sf  & sd" /><arg cat="Two" subj="sdaf asdfsd" other="Isdfsdf sdsdf sf sd" /><arg cat="Three" subj="sddfsr4d" other="Isgfsdt56sf sd" /></whatever>

Is that even possible? Call another XML in one xml?...

Link to comment
Share on other sites

I think the solution might be str_replace. But I can't get it to workI just need the &, ", '$change = array("&", '"', "'");$changed = array("&", "'", """);$changing = str_replace($change,$changed,$write_string); ...that's wrong...enven if it worked it work also convert the quotes after the "=s" so it would result in that error. jfklsdjflkj!!!!

Link to comment
Share on other sites

You're putting too much PHP into it. That's my whole point.Consider something a bit more simpler:

<?php//You generate an XML element with the desired data in it.//Special characters are escaped to avoid non-well formdness.$input = '<img cat="' . htmlspecialchars($_POST['cat']) . '" id="'. htmlspecialchars($_POST['id']) . '" />'//You assign that very same XML element as a parameter to an XSLT transformation.$args = array('input' => $input);//The XML file that will serve the transformation will be the file you want to edit.$xmlfile = "xml.xml";//The XSLT is the one demonstrated above or something similar (I'll look over it if something's wrong)$xslfile = "xsl.xsl";//Initiate the transformation$engine = xslt_create();$output = xslt_process($engine, $xmlfile, $xslfile, NULL, NULL, $args);xslt_free($engine);//Here comes the nasty part.//You don't need to print the output with "print $output" as you normally do.//Instead, first delete the old fileunlink($xmlfile)//Then, create a new file with the output as it's content$handle = fopen($xmlfile, 'w+');if (fwrite($handle, $output) === FALSE) {       echo "Cannot create the new file " . $xmlfile;       exit;   }   echo "Success!";fclose($handle);?>

Link to comment
Share on other sites

I'm not sure if that will work...as in adding new elements to an xml.Also if it does work...the w+ will convert the &amp's (and ect) back to the unconverted form of &.Have you tried this? I hope I'm mistaken.

Link to comment
Share on other sites

I was hoping you'll try it. Simply because it's easier with me. As I said, PHP5 has transformToURI() which works perfectly for this case. But I don't have PHP4 to test the above PHP.If the special characters in the $input PHP variable are escaped, you may use <xsl:value-of select="$input" disable-output-escaping="yes"/> in the XSLT to restore the original characters.

Link to comment
Share on other sites

thanks to the help of boen_robot... this is solved!

boen_robot is a living legend

THe next addition to this will be to add a "delete" in the form and a "Edit"Here's all the code:Process.php:

<?php$input = '<img cat="' . htmlspecialchars($_POST['cat'], ENT_QUOTES) . '" id="'. htmlspecialchars($_POST['id'], ENT_QUOTES) . '" />';$args = array('input' => $input);$xmlfile = "xml.xml";$xslfile = "xsl.xsl";$engine = xslt_create();$output = xslt_process($engine, $xmlfile, $xslfile, NULL, NULL, $args);unlink($xmlfile);$handle = fopen($xmlfile, "w+");fwrite($handle, $output);fclose($handle);xslt_free($engine);print "New Content Added Successfully";print "<br />";print "<a href=\"index.html\" title=\"return\">Return</a>";?>

xsl.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:param name="input"/><xsl:template match="/*" ><xsl:element name="{name()}"><xsl:copy-of select="*"/><xsl:value-of select="$input" disable-output-escaping="yes"/></xsl:element></xsl:template></xsl:stylesheet>

xml output is equal to:

<?xml version="1.0" encoding="UTF-8"?><name><img cat="and I quote" id=""two"" /></name>

index.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Untitled Document</title></head><body><form action="process.php" method="post"><input name="cat" type="text"/><br /><input name="id" type="text"/><br /><input type="submit" /></form></body></html>

Link to comment
Share on other sites

This isn't working 100% now... or maybe it's how it was all the time. you need to start the xml with:<?xml version="1.0" encoding="UTF-8"?><name><img cat="and I quote" id="gfh" two="hfgh" /></name>...to get this to work.boen_robot any ideas on updates and deletions?

Link to comment
Share on other sites

What exactly is the problem with the XML output/input? The encoding? If so, then simply adjust it with <xsl:output encoding="whatever you want"/>. If it's the need for a root element... yes. Your inital document must be a well formed XML document and well formed XML documents have at least a root element (no need for <img/>) and an XML prolog (tweakable by the xsl:output element).As for updates and deletions, I haven't even touched my bag today, so I don't have anything new, but I already have the basic idea. Simply copy each element shallowly(xsl:copy, not xsl:copy-of), exept the one matching certain criterias.

Link to comment
Share on other sites

As for updates and deletions, I haven't even touched my bag today, so I don't have anything new, but I already have the basic idea. Simply copy each element shallowly(xsl:copy, not xsl:copy-of), exept the one matching certain criterias.
Post any ideas? I want to know what you are thinking. I'm thinking have a select field in the form that has three choices: Add, Delete, Edit. These "Add, Delete, Edit" passed as params that call different templates in the XSL, one for Add, one for Delete, one for Edit. If you want to delete or add you have to call the element by it's title or assigned id or whatever. But that's just the starting of this. hmmmmmmmmmm
Link to comment
Share on other sites

I don't have an XSLT yet, but honestly said, I'm starting to like the DOM methods better for theese type of tasks.In the past few days I've tryed expanding my DOM knowledge a bit, and it seems PHP's DOM abilities to remove and replace nodes are just perfect for all that stuff.There's only one minor problem... and I bet you know it... yes... it's PHP5 only. PHP4 has it's own DOM functions which I haven't tryed, but I don't plan to either, as they are deprecated in PHP5 in favor of their new equivalents.

Link to comment
Share on other sites

boen_robot.... long time no talk...Hey...post that php5 code you were working on the other day... I think I have an idea, but I forgot what you had. ....or did you get that to work? (The php5 add, delete, edit form...)

Link to comment
Share on other sites

I've been recetly playing Need For Speed: Carbon, alongside Guild Wars, so I hadn't touched the script scince we last left it:XMLmanipulator.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><title>Edit form</title><head></head><body><form action="XMLmanipulator.php" method="post">	<select id="action" name="action">		<option value="add">add</option>		<option value="remove">remove</option>		<option value="edit">edit</option>	</select>	<input type="submit"/></form></body></html>

XMLmanipulator.php

<?php//Prepare the variables and constants$xmlFile = "photo.xml";	//Your XML file$action = $_POST["action"];	//What are we going to do with it$DBroot = "images";	//This is the element storing everything else.$DBunit = "img";	//The elements you have in the pseudo DB.//Prepare the XML file.$dom = new DomDocument;$dom->load($xmlFile);$xpath = new DomXPath($dom);//Perform the desired actionswitch($action){	case "add":		$parent_path = "/" . $DBroot;		$next_path = "/" . $DBroot . "/" . $DBunit . "[position()=1]";		// Find parent node		$parent = $xpath->query($parent_path);		// new node will be inserted before this node		$next = $xpath->query($next_path);		// Create the new element		$element = $dom->createElement($DBunit);				//A pathetic attempt to create an attribute within the new element.		//Commented for the sake of what's already working.		/*$cat = $dom->createAttribute('cat');		$catText = $dom->createTextNode('TEXT');		$newDBunit = $dom->appendChild($element);*/				// Insert the new element		$parent->item(0)->insertBefore($element, $next->item(0));		$content = $dom->saveXML();		break;	case "remove":		echo "REMOVE Not implemented";		break;	case "edit":		echo "EDIT Not implemented";		break;}//Save the output and notify if there are any errors.if (file_put_contents($xmlFile,$content)== FALSE){echo "Error writing to file";}else{echo "File written successfully. " . file_put_contents($xmlFile,$content) . " bytes written.";}?>

Important: I realized that in this form, when you click REMOVE or EDIT, the file_put_contents() attempts to do the writing, returns an error and a message AND THE FILE'S CONTENT IS GONE. When EDIT and REMOVE are ready, this won't happen. A temporary fix would be to move the function and it's check back to the 'case "add"'.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...