问题
I have a xml just like below:
<data>
<foo>value1</foo>
<foo>value2</foo>
<foo>value3</foo>
</data>
I want to create macrodef which implements below function:
<?xml version="1.0"?>
<project name="OATS" default="execute" basedir=".">
<xmlproperty file="data.xml" collapseAttributes="true"/>
<target name="execute">
<foreach list="${data.foo}" target="runScript" param="script"/>
</target>
<target name="runScript">
<echo>Doing things with ${script}</echo>
</target>
</project>
Anybody knows how to ? Thanks in advance.
回答1:
xmltask is the best choice in the Ant community for this purpose, and you don't have to define your own macrodef.
So for instance:
<tools:xmltask source="data.xml" report="false" >
<tools:call path="data/foo">
<param name="value" path="text()"/>
<actions>
<echo>Doing things with @{value}</echo>
</actions>
</tools:call>
</tools:xmltask>
I encourage you to read the user manual, for xmltask has lots of options. It basically supports XPath to extract and iterate any portion of your xml. It also supports calls to existing targets in addition to anonymous code blocks (as in the example).
It's just hard to beat.
回答2:
The following example uses the groovy ANT task
<project name="OATS" default="execute" basedir=".">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
<classpath>
<pathelement location="lib/groovy-all-2.1.0-rc-2.jar"/>
</classpath>
</taskdef>
<target name="execute">
<groovy>
def data = new XmlSlurper().parse(new File("data.xml"))
data.foo.each {
properties["script"] = it
ant.project.executeTarget("runScript")
}
</groovy>
</target>
<target name="runScript">
<echo>Doing things with ${script}</echo>
</target>
</project>
回答3:
This is my macrodef.
<?xml version="1.0" encoding="UTF-8"?>
<project name="OATS" default="test" basedir=".">
<property environment = "env"/>
<path id = "antcontrib.path">
<fileset file = "${env.ANT_HOME}/../net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar"/>
</path>
<taskdef resource="net/sf/antcontrib/antlib.xml" classpathref="antcontrib.path"/>
<macrodef name="runOATS">
<attribute name="suite"/>
<attribute name="toDir"/>
<sequential>
<delete dir="@{toDir}"/>
<mkdir dir="@{toDir}"/>
<xmlproperty file="@{suite}" collapseAttributes="true"/>
<for list="${data.foo}" param="script">
<sequential>
<runScript script="@{script}"/>
</sequential>
</for>
</sequential>
</macrodef>
<macrodef name="runScript">
<attribute name="script"/>
<sequential>
<echo>Doing things with @{script}</echo>
</sequential>
</macrodef>
<target name="test">
<runOATS toDir="/OATS/results" suite="data.xml"/>
</target>
</project>
来源:https://stackoverflow.com/questions/14457360/how-to-foreach-in-a-macrodef