tags:

views:

575

answers:

3

Hi, I am wondering if there is any way to create a batch file that can edit a line in an XML document. The line would be identified by the preceding line. the idea would be as follows:

If line == Csetting name="BaseDirectory" serializeAs="String">
    Next line = <value>User Input from begining of batch</value>

is something like that even posible or am I dreaming outside of my means? Thanks for the help and the answers.

+3  A: 

You probably could hack something together in a batch file that works somehow. But it will be extraordinarily painful. First of all, I know of no way of reliably reading lines into variables in a batch file and writing them back to a file unaltered. You can escape most of the problematic characters (such as <, >, &, |, ...) but there still are problems I couldn't solve1 (such as unmatched quotation marks) that will cause such attempts to fail horribly. Then you still wouldn't be able to parse XML but you'd rather to primitive text processing which may easily fail as soon as maybe single quotes are used instead of double quotes. Or an extra space is thrown in somewhere. Or the line you're looking for is split into several lines. All valid XML but painful to parse when no XML parser is around.

The batch file language isn't really suited for such tasks. Heck, it barely works for text processing but XML is way beyond. You may have more luck (and fun) with using VBScript and MSXML or even PowerShell (if applicable).

VBScript is probably the most sane choice here as you can rely on it existing on virtually any modern Windows machine.

You could also use XSLT and call that from the command-line. There are enough XSLT processors out there that can be used and generating an XSLT file is actually much simpler (but will still require several escapings).


1 Note that I may be an advanced batch file user/programmer but by no means authoritative. Maybe it's easily possible and I'm just too stupid to see it.

Joey
You're right, it's not possible with standard windows batch commands.
Binary Worrier
its possible. just that you will need more time and effort
ghostdog74
Joey
Thanks for the input. I have a batch file that will be running other processes on a dll with a .config (XML Format) attached. I was hoping there was an easy way to lump in some config editing with the batch, but it appears not. Thanks again for the quick but still very well put answer!
Adkins
+1  A: 

sure, natively, you can use batch, but i recommend you to learn and use vbscript instead

Set objFS=CreateObject("Scripting.FileSystemObject")
strFile = WScript.Arguments.Item(0)
strUserValue= WScript.Arguments.Item(1)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
    If  InStr(strLine,"Csetting name") >0 And _
     InStr(strLine,"BaseDirectory")> 0 And _
     InStr(strLine,"serializeAs=") > 0 Then  
     strLine=strLine & vbCrLf & "<value>" & strUserValue & "</value>"  
    End If 
    WScript.Echo strLine
Loop

save the script as edit.vbs and in your batch

c:\test> cscript //nologo edit.vbs file "user value"

vbscript is the best you got besides cripple batch, if you hate the idea of using other tools like gawk/sed/Python/Perl or other xml parsers/writers. Otherwise, you should consider using these better tools.

ghostdog74
(shudder) I'm not downvoting, but every time I've used MS Basic it's been with extreme reluctance and much frustration.
Jason S
@Jason S - could you recommend a better alternative please. Thanks!
Adkins
A: 

XML isn't line-based, so an assumption that you can look for something in the file by checking it on a line-by-line basis, is either prone to problems, or relies on other assumptions besides XML. (if you are getting your file from a certain type of software, how do you know it is always going to produce output lines in that particular way?)

Having said that, I'd take a look at JSDB Javascript, which has E4X built-in. E4X makes it particularly simple to manipulate XML, as long as you can read it all into memory; it's not a stream-based system. Though you could use JSDB without E4X and handle file I/O using streams:

var Sin = new Stream('file://c:/tmp/testin.xml');
var Sout = new Stream('file://c:/tmp/testout.xml','w');
while (!Sin.eof)
{
   var Lin = Sin.readLine();
   var Lout = some_magic_function(Lin); // do your processing here
   Sout.writeLine(Lout);
}
Sin.close(); Sout.close();
Jason S