Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I write a script to modify an XML file?

Status
Not open for further replies.

01chris

Technical User
Dec 15, 2006
11
GB
I am very new to both Perl and XML but was wondering how I could write a script which would take data from a web form and add it to an XML file. Basically I just wanna add users to my Filezilla server from a web form. The script needs to take the data from the form, add it to the XML file (in the right place) and then restart filezilla server.exe. Oh and "the right place" in the XML file will change every time so the script will need to find the last </User> tag and add new lines beneath it.

I hope that all makes sense.
So could somebody please advise me how to do this.

Thanks, Chris
 
To add data after the last </user> tag, you could use something like:
[tt]
$xml=~s/(.*<\/user>)/$1$webdata/i;
[/tt]
where $xml is the existing XML, and $webdata is the data you're adding, marked-up with its own tags.
 
TonyGroves,
thank you very much for your prompt reply however I'm not sure i understand it. I tried:

Code:
#!c:\Perl\bin\perl.exe
abc.xml=~s/(.*<\/user>)/hello/i;

just to try it out but it didnt work. (I was hoping that it would add "hello" on a new line after the last </user> tag but the script won't run and the XML file remains un-touched).

My Apache error log says:
"[Sat Dec 16 14:21:41 2006] [error] [client 127.0.0.1] Can't modify constant item in substitution (s///) at C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/1.pl line 10, near "s/(.*<\\/user>)/hello/i;"\r

[Sat Dec 16 14:21:41 2006] [error] [client 127.0.0.1] Execution of C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/1.pl aborted due to compilation errors.\r"

What am I doing wrong?

Chris
 
You have to read in the file first, then do the editing, then write it out again. Your example could be as follows:
[tt]
# read file
open F,'<abc.xml' or die "Can't open input file!";
$xml=join('',<F>);
close F;

$webdata='hello';

# capture the xml up to and including the last </user> tag,
# replace it with the same text with $webdata appended.
$xml=~s/(.*<\/user>)/$1$webdata/i;

# write file
open F,'>abc-out.xml' or die "Can't open output file!";
print F $xml;
close F;
[/tt]
 
Thanks again TonyGroves,

I ran the script you posted and it opened the file ok but added "hello" after the 1st </user> tag rather than the last one. Also, could I change "$webdata" to "$FORM{'username'}"? Finally, if I changed "abc-out.xml" to "abc.xml" would it overwrite the unmodified "abc.xml" ok?

Thanks
Chris
 
Sorry, that should have been (to make it handle a multi-line string):
[tt]
$xml=~s/(.*<\/user>)/$1$webdata/is;
[/tt]
Since your program has already closed the input file, the same file can later be opened for writing. You can also use $FORM{'username'} if you want. Just try it and see!
 
Sorry about this but I have yet another question (or 2). How do I enter a few lines of text rather than just one word? For example, after the last </user> tag I want to make a new line then add the following code:
Code:
<User Name="$FORM{'name'}">
  <Option Name="Pass">[COLOR=red] MD5 [/color] </Option> 
  <Option Name="Group">users</Option> 
  <Option Name="Bypass server userlimit">2</Option> 
  <Option Name="User Limit">0</Option> 
  <Option Name="IP Limit">0</Option> 
  <Option Name="Enabled">2</Option> 
  <Option Name="Comments" /> 
  <Option Name="ForceSsl">2</Option>

Also, how do I take data from a form and convert it to MD5, then assign it to a variable so I can replace "MD5" (in red, on the 2nd line) with that variable?

I hope that last bit makes sense

Chris
 
Use \n for line breaks:
[tt]
line 1\nline 2\nline 3
[/tt]
Another way is to use a "here document":
[tt]
$newdata=<<END;
line 1
line 2
line 3
END
# rest of code ...
[/tt]
 
I didn't notice the MD5 bit. You could check out the Digest::MD5 module.
 
Thank you very much for all your help, I think I am nearly there now. Just one last thing, how do I assign
Code:
 use Digest::MD5 qw(md5_hex);
md5_hex("$FORM{$password}")
to $md5. So I can put $md5 every time I want to use the MD5 of what ever the user entered in the "password" field of the form.
 
That's really quite basic.
[tt]
$md5=md5_hex($FORM{$password});
[/tt]
 
Thanks, but I wanted it to work out the MD5 of what was entered into the form and assign that to the $md5 variable, not just assign md5_hex... to it.
 
Please ignore my last post, I was trying to make it more complicated than it needed to be. I think I have done it now, so thank you very very much for all your help and for being so patient with me. I may need to re-post but I doubt it now.

Thanks once again
Chris
 
Have you tried it out to see what happens? I think you'll find it does what you want.

Do you understand what's happening here?
$FORM{$password} returns the password entered.
md5_hex($FORM{$password}) returns the MD5 hash of the password.
$md5=md5_hex($FORM{$password}) assigns that MD5 hash to $md5.
 
Just a little question: When I use
Code:
 $webdata=<<END;

<User Name="$FORM{'username'}">
<Option Name="Pass">"$FORM{password}"</Option>
<Option Name="Group">users</Option>
<Option Name="Bypass server userlimit">2</Option>
<Option Name="User Limit">0</Option>
<Option Name="IP Limit">0</Option>
<Option Name="Enabled">2</Option>
<Option Name="Comments" />
<Option Name="ForceSsl">2</Option>
</user>
END

Why does it put a blank line underneath?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top