title: ANT task - multiple files - loop through
body: <p>I have quite complicated ant task to write. I had to make separate builds files and 1 left. 
  There are 4 files: </p>
  
  <pre><code> buildpackage.bat, buildpackage.xml, buildpackage.txt, structure.xml
  </code></pre>
  
  <p>buildpackage.bat is just an ant file that calls <code>buildpackage.xml "ant -f buildpackage.xml"</code>. That is fine. </p>
  
  <p>buildpackage.txt is simple and has got comma-separated lines:</p>
  
  <pre><code>server1,client1
  server2,client2
  genericserver,client[x]
  server[x],client[x]
  </code></pre>
  
  <p>There is always server name and client name:</p>
  
  <ul>
  <li><p><code>Server name</code> can be letters only, numbers and letters but has variable length.</p></li>
  <li><p><code>Client name</code> - letters only. </p></li>
  </ul>
  
  <p>I need to split those files into 2 separate variables: <code>server.name</code> and <code>client.name</code>.</p>
  
  <p>What I have done is:</p>
  
  <pre><code>&lt;loadfile property="buildpackage" srcFile="buildpackage.txt"/&gt;    
  &lt;for list="${buildpackage}" param="depl.det" delimiter="${line.separator}"&gt;
   &lt;sequential&gt;
    &lt;echo&gt;
     Input:   @{deploy.details}
    &lt;/echo&gt;
   &lt;/sequential&gt;
  &lt;/for&gt;
  </code></pre>
  
  <p>The results I get are:</p>
  
  <pre><code>[echo] Input:   server_01,Client_01
  [echo] Input:   server_02,Client_02
  [echo] Input:   server_03,Client_03
  [echo] Input:   clientserver,client_04
  </code></pre>
  
  <p>I would like server_01 to be parameter1 and client_02 to be parameter2.</p>
  
  <p>I will perform other tasks in a sequence. I will copy files from client[x] directory to server[x] (that is simple but how do I split that string into 2 separate variables?).</p>
  
  <p>And now the very complicated task.</p>
  
  <p>I also have structure.xml file. The structure is:</p>
  
  <pre><code> &lt;core&gt;
     &lt;clients&gt;
       &lt;client&gt;
         &lt;name&gt;Client_01&lt;/name&gt;
         &lt;branding&gt;brand_01&lt;/branding&gt;
         &lt;applications&gt;
           &lt;application&gt;application_01&lt;/application&gt;
         &lt;/applications&gt;
         &lt;solutions&gt;
           &lt;solution&gt;solution01&lt;/solution&gt;
         &lt;/solutions&gt;
     &lt;/client&gt;
     &lt;client&gt;
       &lt;name&gt;Client_07&lt;/name&gt;
       &lt;branding&gt;brand_09&lt;/branding&gt;
       &lt;applications&gt;
         &lt;application&gt;application_03&lt;/application&gt;
       &lt;/applications&gt;
       &lt;solutions&gt;
         &lt;solution&gt;solution01&lt;/solution&gt;
         &lt;solution&gt;solution07&lt;/solution&gt;
         &lt;solution&gt;solution08&lt;/solution&gt;
       &lt;/solutions&gt;
     &lt;/client&gt;
    &lt;clients&gt;
   &lt;core&gt;
  </code></pre>
  
  <p>I have plenty of clients, applications, brandings, solutions. Each client can have only 1 application and 1 branding but multiple solutions.</p>
  
  <p>Based on previous sequential task (get server and name) I have to loop through that xml file and get for each matching client (from previous task)</p>
  
  <pre><code>- branding
  - application 
  - solutions (multiple or one) 
  </code></pre>
  
  <p>I can read XML using <code>&lt;xmlproperty&gt;</code> but I do not know how to do it sequentially (iterate) and get matching properties. </p>
  
  <p>I know it is complicated. The summary is: </p>
  
  <ol>
  <li>build script starts </li>
  <li>build script extracts data from buildpackage.txt as client.name and server.name</li>
  <li>build script gets <code>${client.name}</code> from step 2 as a parameter and loops through structure.xml. It finds matching branding/application/solutions and outputs it for each matching client.</li>
  </ol>
  
  <p>Output:</p>
  
  <pre><code>server.name
  client.name
  branding.name
  application name
  solution [X]
  solution [y]
  </code></pre>
  
  <p>Ant has to be processed for each server/client. I can do the rest of the build and compile if I have the properties. I can not touch structure.xml. I can do all I need/want to buildpackage.cml and buildpackge.txt. Buildpackage.txt could be replaced by .xml file or any file (for example .properties). It has to contain those 2 values server and client.</p>
  
  <p>Thank you for your help.</p>
  
  <h1>EDIT</h1>
  
  <p>Now i have a problem. 
  If I put same application 2x into a buildfile it builds only first one.
  Here is my <code>build.xml</code> file</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project name="DoTheJob" basedir="." xmlns:ac="antlib:net.sf.antcontrib" xmlns:if="ant:if" xmlns:unless="ant:unless"&gt;
      &lt;!-- Define classpath and default locations--&gt;
      &lt;property name="root.dir" location="../.."/&gt;
      &lt;property name="dest.dir" location="packages"/&gt;
      &lt;property name="ant.lib.dir" location="../lib"/&gt;
      &lt;property name="repository_url" value="http://repository-url"/&gt; 
      &lt;path id="project.classpath"&gt;
          &lt;fileset dir="${ant.lib.dir}"&gt;
          &lt;include name="*.jar"/&gt;
          &lt;/fileset&gt;
          &lt;fileset dir="${root.dir}/IIT/lib"&gt;
              &lt;include name="*.jar"/&gt;
          &lt;/fileset&gt;
          &lt;pathelement location="../savedjar/compiled.jar"/&gt;
      &lt;/path&gt;
      &lt;path id="svnant.path"&gt;
          &lt;fileset dir="../lib/"&gt;
              &lt;include name="svnant.jar"/&gt;
              &lt;include name="svnClientAdapter.jar"/&gt;
          &lt;/fileset&gt;
      &lt;/path&gt;
      &lt;typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.path" /&gt; 
      &lt;tstamp&gt;
          &lt;format property="build_time" pattern="YYYY MMMM dd HH:mm:ss"/&gt;
      &lt;/tstamp&gt;   
      &lt;!-- Change characters to lowercase --&gt;
      &lt;scriptdef language="javascript" name="lowercase"&gt;
          &lt;attribute name="string" /&gt;
          &lt;attribute name="to" /&gt;
          project.setProperty(attributes.get("to"),attributes.get("string").toLowerCase());
      &lt;/scriptdef&gt;
      &lt;!-- Import XMLTask for XML transformations--&gt;
      &lt;taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpathref="project.classpath"/&gt;
      &lt;!-- Define buildfiles locations--&gt;
      &lt;property name="structure.file" location="../structure.xml"/&gt;
      &lt;property name="buildpackage.file" location="buildpackage.txt"/&gt;
      &lt;!-- load client/server file--&gt;
      &lt;property file="${buildpackage.file}"/&gt;
      &lt;!-- loop over all clients --&gt; 
      &lt;xmltask source="${structure.file}"&gt;
      &lt;call path="//client"&gt;
          &lt;param path="name/text()" name="client"/&gt;
          &lt;param path="branding/text()" name="branding"/&gt;
          &lt;param path="applications/application/text()" name="application"/&gt;
              &lt;actions&gt;
                  &lt;!-- loop through all XML properties only when @{client} condition is matched --&gt; 
                  &lt;ac:if&gt;
                      &lt;isset property="@{client}"/&gt;
                      &lt;then&gt;
                          &lt;echo&gt;=====================================================&lt;/echo&gt;
                          &lt;echo&gt;Building package for @{client} on ${@{client}}       &lt;/echo&gt;
                          &lt;echo&gt;=====================================================&lt;/echo&gt;
                          &lt;!-- creating destination directories --&gt;                           
                          &lt;delete dir="${build.dir}/@{client}"/&gt;
                          &lt;mkdir dir="${dest.dir}/@{client}"/&gt; 
                          &lt;echo&gt;=====================================================&lt;/echo&gt;
                          &lt;echo&gt;Copy application files code/temaplates to destination&lt;/echo&gt;
                          &lt;echo&gt;=====================================================&lt;/echo&gt;                      
                          &lt;!-- creating code build directory --&gt;
                          &lt;mkdir dir="${dest.dir}/@{client}/code"/&gt; 
                          &lt;!-- copy application code --&gt; 
                          &lt;echo&gt;copy application code&lt;/echo&gt;
                          &lt;copy todir="${dest.dir}/@{client}/code/application/@{application}" overwrite="yes"&gt;
                              &lt;fileset dir="${root.dir}/client-source/application/@{application}" includes="**/*.*"/&gt;
                          &lt;/copy&gt;
                          &lt;!-- copy application templates --&gt; 
                          &lt;mkdir dir="${dest.dir}/@{client}/app/@{client}"/&gt; 
                          &lt;echo&gt;copy application templates&lt;/echo&gt;
                          &lt;copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"&gt;
                              &lt;fileset dir="${root.dir}/applications/apps/@{application}" includes="**/*.*"/&gt;
                          &lt;/copy&gt;
                          &lt;echo&gt;===================================================&lt;/echo&gt;
                          &lt;echo&gt;copy Solutions files code/temaplates to destination&lt;/echo&gt;
                          &lt;echo&gt;===================================================&lt;/echo&gt;    
                          &lt;!-- nested xmltask for loop over solutions --&gt;
                          &lt;xmltask source="${structure.file}"&gt;
                              &lt;call path="/core/clients/client[name/text()='@{client}']/*/solution"&gt;
                                  &lt;param path="text()" name="solution"/&gt;
                                      &lt;actions&gt;
                                          &lt;!-- making sure that solution is lowercase --&gt;
                                          &lt;lowercase string="@{solution}" to="solution.lowercase" /&gt;
                                          &lt;echo&gt;copy solutions code&lt;/echo&gt;
                                          &lt;!-- copy solutions code --&gt;
                                          &lt;copy todir="${dest.dir}/@{client}/code/solutions/${solution.lowercase}" overwrite="yes"&gt;
                                              &lt;fileset dir="${root.dir}/client-source/solutions/${solution.lowercase}" includes="**/*.*"/&gt;
                                          &lt;/copy&gt;
                                          &lt;!-- copy solutions templates --&gt;
                                          &lt;echo&gt;copy Solutions templates&lt;/echo&gt;
                                          &lt;copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"&gt;
                                              &lt;fileset dir="${root.dir}/applications/solutions/${solution.lowercase}" includes="**/*.*"/&gt;
                                          &lt;/copy&gt;
                                      &lt;/actions&gt;
                              &lt;/call&gt;
                          &lt;/xmltask&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt;
                          &lt;echo&gt;copy Client files code/temaplates to destination&lt;/echo&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt; 
                          &lt;!-- copy branding directory --&gt; 
                          &lt;copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"&gt;
                              &lt;fileset dir="${root.dir}/applications/brandings/@{branding}" includes="**/*.*"/&gt;
                          &lt;/copy&gt;                         
                          &lt;!-- copy client code --&gt; 
                          &lt;copy todir="${dest.dir}/@{client}/code/client/@{client}" overwrite="yes"&gt;
                              &lt;fileset dir="${root.dir}/client-source/client/@{client}" includes="**/*.*"/&gt;
                          &lt;/copy&gt;                         
                          &lt;!-- set templates directory --&gt; 
                          &lt;copy todir="${dest.dir}/@{client}/app/@{client}" overwrite="yes"&gt;
                              &lt;fileset dir="${root.dir}/applications/clients/@{client}" includes="**/*.*"/&gt;
                          &lt;/copy&gt;         
                          &lt;echo&gt;==============================================&lt;/echo&gt;
                          &lt;echo&gt;compiling code                                &lt;/echo&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt; 
                          &lt;!-- making classes directory --&gt; 
                          &lt;mkdir dir="${dest.dir}/@{client}/classes"/&gt;
                          &lt;javac destdir="${dest.dir}/@{client}/classes" classpathref="project.classpath" debug="on" fork="true" includeantruntime="false" memoryinitialsize="256m" memorymaximumsize="1024m"&gt;
                              &lt;src path="${dest.dir}/@{client}/code/"/&gt;
                          &lt;/javac&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt;
                          &lt;echo&gt;creating Client.jar                           &lt;/echo&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt; 
                          &lt;!-- jar classes directory --&gt; 
                          &lt;jar jarfile="${dest.dir}/@{client}/app/Client.jar" basedir="${dest.dir}/@{client}/classes"/&gt;
                          &lt;!-- reaplce text in files --&gt; 
                          &lt;replaceregexp byline="true"&gt;
                              &lt;regexp pattern="@ReleaseDate@"/&gt;
                              &lt;substitution expression="${build_time}"/&gt;
                              &lt;fileset dir="${dest.dir}/@{client}/app/@{client}/templates/"&gt;
                                  &lt;include name="*.htm"/&gt;
                                  &lt;include name="*.html"/&gt;            
                                  &lt;include name="*.ini"/&gt;
                              &lt;/fileset&gt;
                          &lt;/replaceregexp&gt;
                          &lt;!-- get svn info --&gt; 
                          &lt;svn username="********" password="************" javahl="false" svnkit="false"&gt;
                              &lt;info target="${repository_url}" /&gt;
                          &lt;/svn&gt;
                          &lt;!-- creating Client.ini file --&gt; 
                          &lt;touch file="${dest.dir}/@{client}/app/Client.ini"/&gt;
                          &lt;concat destfile="${dest.dir}/@{client}/app/Client.ini" append="true"&gt;releaseDate=${build_time}${line.separator}&lt;/concat&gt;
                          &lt;concat destfile="${dest.dir}/@{client}/app/Client.ini" append="true"&gt;svnrevision=${svn.info.lastRev}${line.separator}&lt;/concat&gt;
                          &lt;!-- ziping package --&gt; 
                          &lt;zip destfile="${dest.dir}/@{client}/@{client}.zip" basedir="${dest.dir}/@{client}/app/" /&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt;
                          &lt;echo&gt;sending @{client}.zip to the server via scp      &lt;/echo&gt;
                          &lt;echo&gt;==============================================&lt;/echo&gt; 
                          &lt;!-- scp file to remote server --&gt;
                          &lt;property name="scp_username" value="**********"/&gt;
                          &lt;property name="scp_password" value="**********"/&gt;
                          &lt;property name="scp_server" value="${@{client}}"/&gt;
                          &lt;property name="scp_remote_directory" value="*********"/&gt;
                          &lt;scp trust="true" verbose="true" localFile="${dest.dir}/@{client}/@{client}.zip" remoteTodir="${scp_username}:${scp_password}@${scp_server}:${scp_remote_directory}"/&gt;  
                          &lt;echo&gt;${line.separator}${line.separator}${line.separator}&lt;/echo&gt;
                      &lt;/then&gt;
                  &lt;/ac:if&gt; 
              &lt;/actions&gt;
          &lt;/call&gt;
      &lt;/xmltask&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>And if I try yo build <code>buildpackage.txt</code> file</p>
  
  <pre><code>client1=server1
  client2=server1
  client1=server2
  </code></pre>
  
  <p>I do get 
  client1->server1, client2->server1 but ...... no client 1to server2</p>
  
  <h1>EDIT2</h1>
  
  <p>All fixed.
  The solution for scp task is: </p>
  
  <pre><code>       &lt;!-- scp file to remote server --&gt;
          &lt;property name="scp_username" value="XXX"/&gt;
          &lt;property name="scp_password" value="YYY"/&gt;
          &lt;property name="scp_remote_directory" value="path"/&gt;
          &lt;for list="${@{client}}" delimiter="=" param = "val"&gt;
              &lt;sequential&gt;
              &lt;property name="token" value="@"/&gt;
              &lt;scp trust="true" verbose="true" localFile="${dest.dir}/@{client}/@{client}.zip" remoteTodir="${scp_username}:${scp_password}${token}@@{val}:${scp_remote_directory}"/&gt; 
          &lt;/sequential&gt;
          &lt;/for&gt;
  </code></pre>
  
  <p>All works.
  Thank you for your help</p>