tags:

views:

839

answers:

3

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.

A: 

Try putting the XML in a CDATA section:

<loadfile
  property="xmlStuff"
  srcFile="xmlFile.xml">
<![CDATA[
  <filterchain>
    <striplinebreaks/>
  </filterchain>
]]>
</loadfile>
Jim Garrison
I don't think you understand, I want to striplinebreaks. The problem is the contents of the file. I tried putting CDATA around the text in arg's value attribute, but this isn't allowed in ANT.
Adam
Can't you include the XML in a CDATA section as the text value of the arg tag -- i.e. <arg>cdata section with xml</arg> ?
Jim Garrison
Arg doesn't support nested text.Error:class org.apache.tools.ant.types.Commandline$Argumentdoesn't support nested text data
Adam
+1  A: 

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.

Jukka Matilainen
would there be any way to force ant not to use quotes around the arg in the final command? I've found that's the real clincher because I can't change "theCommand"
Adam
Using the `line` attribute instead of `value` allows you to specify a space-delimited list of command-line arguments: `<arg line="foo bar baz"/>` This way it won't add the quotes in there, but you get the value split into different arguments by whitespace.
Jukka Matilainen
thanks jackem, that's what I needed!
Adam
A: 

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.

Adam