3

I am attempting to dynamically create a small XML file with a Batch Script, but am having issues writing lines that begin and end with angle brackets.

1) If I do something like:

set foo=^<bar^>
echo %foo% > test.txt

This results in

> was unexpected at this time.
echo <bar> > test.txt


2) If I surround the echo statment variable with quotes: echo "%foo%" > test.txt, it writes successfully to the text file. However it obviously includes the quotes which I can't have.


3) Then I thought "Well, it must just be the angle brackets at the beginning and end..." So I added a character before and after the angle brackets:

set foo=a^<bar^>a
echo %foo% > test.txt

This resulted in some weird output which looks like my brackets are being numbered, and then it's looking for a file?

echo a 0<bar 1>test.txt
The system cannot find the file specified.


I've written elementary batch scripts before, but feel like I'm in over my head here... Any help is appreciated!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
sǝɯɐſ
  • 2,470
  • 4
  • 33
  • 47
  • 1
    How about using a [batch script heredoc](http://stackoverflow.com/a/15032476)? It works well enough for [generating html](http://stackoverflow.com/a/27652107/1683264). – rojo Jan 09 '15 at 01:01

4 Answers4

4

Try this:

setlocal ENABLEDELAYEDEXPANSION

set foo=^<bar^>
echo !foo! > test.txt

endlocal

Using delayed expansion, and replacing the % with ! causes it to evaluate it differently.

James L.
  • 9,384
  • 5
  • 38
  • 77
3

If using a pipe you need:

set foo=^^^<bar^^^>
Alex K.
  • 171,639
  • 30
  • 264
  • 288
2

You need to account for double substitution:

set foo=^^^<bar^^^>
echo %foo% > test.txt
nwk
  • 4,004
  • 1
  • 21
  • 22
1

I am attempting to dynamically create a small XML file with a Batch Script

Stop what you are doing, scrap it. Batch script is not a tool you should use to create XML, and even though you can bang on it for long enough to make it work in a specific case, it still isn't the right tool to create XML files.

If you want ubiquitous, no configuration or special permissions needed, runs on every Windows machine XML creation, that can be done in VBScript, using an actual XML API (MSXML2).

For a ubiquitous, some configuration and permissions needed approach, you can turn to PowerShell.

I'll provide a code sample if you specify your desired output more closely.


Following up the OP's request in the comments, here is an exemplary setup using VBScript. The key point of course is not which tool to use, but to use a tool that has a semantic understanding of XML.

Base XML template, e.g. project_template.xml:

<project outputDir="" baseDir="" xmlns="http://confuser.codeplex.com">
  <rule pattern="true" preset="maximum" inherit="false" />
</project> 

VBScript to fill it dynamically, e.g. project.vbs:

Option Explicit

Const NODE_ELEMENT = 1
Const CONFUSER_NS = "http://confuser.codeplex.com"

Dim doc, moduleElem, args, arg

Set args = WScript.Arguments
Set doc = CreateObject("MSXML2.DOMDocument")

doc.async = False
doc.load "project_template.xml"

If doc.parseError.errorCode Then
  WScript.Echo doc.parseError
  WScript.Quit 1
End If

For Each arg In args.Named
  doc.documentElement.setAttribute arg, args.Named(arg)
Next

For Each arg In args.Unnamed
  Set moduleElem = doc.createNode(NODE_ELEMENT, "module", CONFUSER_NS)
  moduleElem.setAttribute "path", arg
  doc.documentElement.appendChild moduleElem
Next

Doc.save "project.xml"

Usage:

cscript /nologo project.vbs /outputDir:"xx1" /baseDir:"xx2" "xx3" "xx4" "xx5"

Output (saved as project.xml)

<project outputDir="xx1" baseDir="xx2" xmlns="http://confuser.codeplex.com">
  <rule pattern="true" preset="maximum" inherit="false"/>
  <module path="xx3"/><module path="xx4"/><module path="xx5"/>
</project>
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Yay, downvote without comment for the only sensible post in the thread. Way to go. – Tomalak Jan 08 '15 at 18:03
  • 1
    Thanks for your answer, and I upvoted to at least cancel out the downvote :). I understand where you are coming from, and normally I wouldn't be trying to create XML this way, but in my case I think it is going to be the most fitting solution. Basically, I need to dynamically create an elementary "configuration" file so that I can run a open source obfuscator which accepts only the path to the config file as command line args... and all of that in the middle of a build process! :P If I run stuck, I will revisit your answer. – sǝɯɐſ Jan 08 '15 at 19:15
  • Thanks. I can understand where you are coming from, too. It's just... not *difficult* to use the right tools, so going out of your way to avoid using them is irrational, isn't it? – Tomalak Jan 08 '15 at 19:21
  • Well.... it's a bit more difficult if you don't know the language... :P Could you supply me with an small vbscript example which could be run from command line that accepts arguments and would dynamically create an XML file with them? I'm not finding much on MSXML2... – sǝɯɐſ Jan 08 '15 at 19:35
  • I could. It would help me if you gave an example of what you need, exactly. For example, easiest situation for me: Fixed base XML structure Y, changed by parameters A, B and C into final result Z. – Tomalak Jan 08 '15 at 19:54
  • That's about all there is too it: ` ` where outputDir, baseDir, and module paths should be specified. Haven't quite worked out how I'm going to pass in or loop through the modules yet. – sǝɯɐſ Jan 08 '15 at 20:21
  • @sǝɯɐſ Done. Have a look. Advantages: Easy to change and extend, no syntax surprises, won't silently generate broken output, easy to maintain. Disadvantages: None, really, if you don't count the slight learning curve as a disadvantage. – Tomalak Jan 08 '15 at 21:12
  • I'm not buying the *"I'm not finding much on MSXML2"* argument, though. The MSDN is choke full of documentation and the general Internet (this site included) full of examples. ;) – Tomalak Jan 08 '15 at 21:20
  • I found a lot of links (including MSDN) that talked mostly about using it with IE, JScript, etc, so I was mostly skipping those... And when the ***first*** page of a Google search for "MSXML2" returns stuff like [http://stefanointelisano.com/download/tycenycy.html](http://stefanointelisano.com/download/tycenycy.html), which is a scary looking download page which says (and I quote) `Eye contact with caustic chemicals meatiesohs. He probably will find the cure to AIDS.`... I consider that as "not much"... lol :P – sǝɯɐſ Jan 08 '15 at 21:32
  • thanks for your help and sample code! I will play around with it and see if I can get it to work for my purposes... I appreciate your responses and wish I could give you more than one upvote :) – sǝɯɐſ Jan 08 '15 at 21:33