I know this post is realy old but now that some time and ant versions passed there is a way to do this with basic ant features and i thought i should share it.
It's done via a recursive macrodef that calls nested tasks (even other macros may be called). The only convention is to use a fixed variable name (element here).
<project name="iteration-test" default="execute" xmlns="antlib:org.apache.tools.ant" xmlns:if="ant:if" xmlns:unless="ant:unless">
<macrodef name="iterate">
<attribute name="list" />
<element name="call" implicit="yes" />
<sequential>
<local name="element" />
<local name="tail" />
<local name="hasMoreElements" />
<!-- unless to not get a error on empty lists -->
<loadresource property="element" unless:blank="@{list}" >
<concat>@{list}</concat>
<filterchain>
<replaceregex pattern="([^;]*).*" replace="\1" />
</filterchain>
</loadresource>
<!-- call the tasks that handle the element -->
<call />
<!-- recursion -->
<condition property="hasMoreElements">
<contains string="@{list}" substring=";" />
</condition>
<loadresource property="tail" if:true="${hasMoreElements}">
<concat>@{list}</concat>
<filterchain>
<replaceregex pattern="[^;]*;(.*)" replace="\1" />
</filterchain>
</loadresource>
<iterate list="${tail}" if:true="${hasMoreElements}">
<call />
</iterate>
</sequential>
</macrodef>
<target name="execute">
<fileset id="artifacts.fs" dir="build/lib">
<include name="*.jar" />
<include name="*.war" />
</fileset>
<pathconvert refid="artifacts.fs" property="artifacts.str" />
<echo message="$${artifacts.str}: ${artifacts.str}" />
<!-- unless is required for empty lists to not call the enclosed tasks -->
<iterate list="${artifacts.str}" unless:blank="${artifacts.str}">
<echo message="I see:" />
<echo message="${element}" />
</iterate>
<!-- local variable is now empty -->
<echo message="${element}" />
</target>
</project>
The key features needed where:
I didnt manage to make the delimiter variabel, but this may not be a major downside.