1
votes

We need to call an executable from ant that takes xml as part of the argument. Using exec is easy enough, but one of the arguments includes an xml file. We tried loading the xml file using the loadfile target with striplinebreaks

<loadfile property="xmlStuff" srcFile="xmlFile.xml">
   <filterchain>
     <striplinebreaks/>
   </filterchain>
</loadfile>
<exec executable="theCommand">
   <arg value="Some other information and now our xml: '${xmlStuff}'" />
</exec>   

Is there a way we can read and escape xml documents for use in this case?

EDIT since xmlStuff has quotes for its attributes they are ending the arg valute attribute quotes.

So the above example ends up like:

theCommand "Some other information and now our xml: '<outerTag myAtt="foobar"> <innerTag /> </outerTag>'"

Instead of:

theCommand Some other information and now our xml: '<outerTag myAtt="foobar"> <innerTag /> </outerTag>'

Is there any way to have essentially three layers of quotes?

One for the value attribute of the arg tag (could these perhaps not be included in the final command?).

One for within the arg tag to represent the nested string.

One for within the xmlStuff for attributes within.

This file is being injected into a database and is not available now.

3
What do you mean by "breaking out of the arg tag"? What is the exact error message you are getting? Works fine for me after fixing the colon after executable and trying with an executable which just echoes its arguments.Jukka Matilainen
Thanks about the colon. I've updated the question a bit, but after evaluating ${xmlStuff} the arg tag will look like: <arg value="Some other information and now our xml: <foo><bar /></foo>" /> The embedded xml is the big problem.Adam
Are you sure that the variable expanding to a value containing angle brackets is actually your problem? As I understand it, Ant expands the variable references after parsing the XML, so it cannot affect parsing. I tried with your example and it does work for me. How exactly did you test, and what error did you get?Jukka Matilainen
Your right, the test case seems to be working. I created it by using the same format as in production. I'll try to test in production again and post the error as well as what differs between my example and production.Adam
Ok, so the problem seems to actually be that the quotes aren't escaping as expected. I'll update the question appropriatly. The error message in production is from the command saying that there are too many arguments.Adam

3 Answers

2
votes

Double quotes in the value of the value attribute of the arg tag seem to cause problems on Windows (but not on Linux; tested with Ant 1.7.1).

If breaking on other platforms is not a concern, I guess a crude workaround could be just escaping the quotes which end up on the command line. You could do this for example by adding the following filter to your filterchain:

<tokenfilter>
  <replacestring from='"' to='\"'/>
</tokenfilter>

Edit: In your own answer you reveal that "theCommand" is actually psql. Since it can read the query from a file using the -f switch, using a temporary file is really the easiest way to avoid command line troubles.

<tempfile property="temp.file" deleteonexit="true" />
<echo file="${temp.file}"
      message="Some other information and now our xml: '${xmlStuff}'" />
<exec executable="psql">
  <arg value="-f" />
  <arg file="${temp.file}" />
</exec>
<delete file="${temp.file}" />

Nevertheless, if you are inserting the XML file contents into a SQL string literal, you should consider at least escaping apostrophes.

0
votes

Try putting the XML in a CDATA section:

<loadfile
  property="xmlStuff"
  srcFile="xmlFile.xml">
<![CDATA[
  <filterchain>
    <striplinebreaks/>
  </filterchain>
]]>
</loadfile>
0
votes

A workaround that we have been using in the meantime has been to use a file based argument instead of a command line argument for "theCommand" (actually postgresql's psql command) and manually adding the "Some other info..."(actually an insert query) to a copy of the xml file. Very messy and hard to maintain, but I thought I would post it.