how i can traverse the xml path dynamically in antscript? - ant

Could anyone tell me, how can I traverse the xml path dynamically in antscript? If the parent tag is given from command line arguement. with this , i have to form child tag path ..access the xml file , to pull the value form the formed xml tag path.
ant -DId=abc
Given file is
<abc>
<Age>16</Age>
</abc>
Is this correct to give output 16?
<echo>${${Id}.Age}</echo>

ANT is not a scripting language, and properties within properties is unfortunately not supported :-(
My suggested solution is an embedded groovy script
<target name="parse">
<groovy>
def data = new XmlSlurper().parse(new File("data.xml"))
println data.Age
</groovy>
</target>
Conveniently (in your case) the groovy xml parser ignores the name of the root tag, meaning you don't have to pass it as a parameter.
See also the following similar question:
How to <foreach> in a <macrodef>?

Related

Issue with the space in the path specified for build.xml

I have a build file, which has the following property in it.
<property name="schema.dir" value="src/main/resources/schema" />
This schema.dir is used to refer a wsdl file.The parent folder which contains the build.xml has a space in it like this folder name .
When I echoed the property it displayed only src/main/resources/schema.
But I can see from the ant logs that issue is with the space in the folder name.
Since the parent folder is having a space in it, I am not able to refer the wsdl.
Can somebody suggest a solution so that file can be accessed with out changing the folder name
Is it possible to provide directly full path to wsdl file?
Try to replace " " sign with "%20".
For test you can hardcode that and with ANT you can use the propertyregex task from Ant Contrib.
See Replacing characters in Ant property
Have you tried specifying your property as a location rather than a string so Ant knows it's dealing with a file path, you can also specify the path as relative to your base directory.
<property name="schema.dir" location="${basedir}/src/main/resources/schema"/>
Adding ${basedir} to the path may not be necessary after changing the property from a value to a location.

Set Ant project name

I am trying to change the ant.project.name property after the project declaration. I know this is not advisable but it's the only way I can fix a big problem with my project.
I found some interesting posts like this one:
Ant - How to set ${ant.project.name} to project folder name?
Instead of using:
<project basedir="." default="package">
<basename property="ant.project.name"
file="${basedir}"/>
</project>
I'd like to directly set the ant.project.name using a "value" instead of a property "file".
Do you have any ideas or suggestions? Or alternative ways?
Thank you!
As others already mentioned, it's not recommended to change values of standard ant properties.
Also properties once set are immutable in ant by design and for good reasons. Overriding properties should be used wisely and rarely.
The property ant.project.name is usually set via name attribute of project =>
<project name="whatever"> but it's not mandatory, means <project> ... </project> is sufficient to make your xml a valid antscript.
In your case <echo>${ant.project.name}</echo> would echo ${ant.project.name}, as property is not set, so you may create it with property task in your script : <property name="ant.project.name" value="whatever"/>. But using a propertyname that is normally used for 'ant internals' seems not the best choice.
If property is set within project tag it's possible to overwrite the value via script task, using builtin javascript engine and ant api, f.e. :
<project name="foo">
<property name="bla" value="foobar"/>
<echo>1. $${ant.project.name} => ${ant.project.name}</echo>
<script language="javascript">
project.setUserProperty('ant.project.name', project.getProperty('bla'));
</script>
<echo>2. $${ant.project.name} => ${ant.project.name}</echo>
</project>
output :
[echo] 1. ${ant.project.name} => foo
[echo] 2. ${ant.project.name} => foobar
Notice : as ant.project.name is not a 'normal' property (those properties declared via property task within ant script), you have to use the method project.setUserProperty(String, String) instead of project.setProperty(String, String). Userproperties are properties defined via -Dkey=value commandline argument and enjoy a special protection.
Ant also provides a bunch of builtin properties

Display Ant options, properties specified in invocation

I have an Ant buildfile (build.xml) which is called by some application. I would like to know exactly what kind of properties are used to invoke Ant. Therefore I would like to modify the build.xml file to display all properties specified in the call, e.g.:
ant aTarget -Dxslt.parser=SAXON -Dbasedir=aFolder
would display list as below
- target: aTarget
- xslt.parser = SAXON
- basedir=aFolder
Please note that I do not know exactly what is being using to invoke Ant. Therefore, I need to use some sort of a loop get all properties, options.
The simplest thing that comes to mind is to place a line like:
<echo message="Ant invocation is '${sun.java.command}'" />
In the buildfile outside of any target. It'll look something like:
% ant aTarget -Dx=y
[echo] ant invocation is: 'org.apache.tools.ant.launch.Launcher -cp . aTarget -Dx=y'
It shows you what was passed to the Ant Launcher, which might will likely be a little more than what was passed to the ant wrapper script, but should do.
I would avoid trying to parse the line, as you say, you don't know what might be there, and it could quickly get complicated.
Take a look at the <echoproperties> task:
<property name="in.file.prop" value="value2"/>
<echoproperties/>
in.file.prop and its value will be printed. However, over 60 other properties will be printed as well including properties built into Ant.
You can save the results of <echoproperties> to a file and then filter that file with something like a <linecontains> filter.

Why does ant mappedresources seem to flatten paths to file names no matter what mapper is used

I'm trying to do something fairly simple: take a path or dirset and extend each of its elements to get a new path.
For example, say I have a path that contains
c:\foo\plugins\com.foo.bar
c:\foo\plugins\com.baz.quux
I want to get a new path with:
c:\foo\plugins\com.foo.bar\src
c:\foo\plugins\com.baz.quux\src
I'm actually using a path based on a dirset for the first path, then using a <mappedresources> to get the second path, but the second path always ends up truncated like this:
com.foo.bar\src
com.baz.quux\src
To simplify for debugging, I removed the path and just stuck the dirset in a mapped resources, then I use a pathconvert macrodef for debug output.
I also replaced the globmapper I was using (for mapping * to */src) with an <identitymapper> just to see if it was the globmapper. It wasn't.
In a nutshell I have this:
<mappedresources id="src.resources">
<dirset dir="c:\foo">
<include name="com.*"/>
</dirset>
<identitymapper/>
</mappedresources>
Now when I dump this with path convert I get
com.foo.bar
com.baz.quux
(Again, this is debugging, in my original I use a globmapper and I get that same list but with "/src" appended - but I'm replacing the globmapper with an identitymapper)
Now, if replace the mappedresources with regular <resources>, I get the full path
<resources id="src.resources">
<dirset dir="c:\foo">
<include name="com.*"/>
</dirset>
</resources>
Then I get the full paths when dumping:
c:\foo\plugins\com.foo.bar
c:\foo\plugins\com.baz.quux
Why?
The ant mapper documentation clearly shows examples of full paths being mapped to full paths with both the globmapper and the identity mapper, and only shows that the <flatten> mapper does something like this. So why is it happening here?
And failing this, is there some better way to get a path that contains all the elements of another path but extended with an extra directory like this?
One last note: I'm using these paths in a custom task, not in a <copy> or other task that takes mappers directly - I'm assuming this wouldn't occur directly in the task, but I haven't tested yet.

Dynamic property names in ant

I am reading a file in ant and loading the properties through loadproperties. I am interested in using the value of a specific property, whose name is not known. I know that it follows a pattern because that is how I load the property.
I can echoproperties and see that it is being loaded.
But I dont know how to access its value, given that its name is actually a pattern rather that hardcoded.
How can I access this property's value to do some processing.
I hope this is clear. Please ask if I need to clarify some more.
Take a look at ant-contrib package. Its propertycopy task will do what you need. If you need to resolve an arbitrary number of properties following an established pattern, you would use ant-contrib's propertycopy in conjunction with ant-contribs "for" task.
http://ant-contrib.sourceforge.net/tasks/tasks/index.html
You should use Ant's script task.
I suggest using the beanshell script since it is pure java.
For example, to print all properties for your project, use the following:
<target name="echoprops">
<script language="beanshell">
System.out.println("All Properties: " + project.getProperties().keySet());
</script>
</target>
It should be easy to modify the above script to get the property you want.
To use this task, you will need to run the following in $ANT_HOME first:
ant -f fetch.xml script -Ddest=user
That will download all required optional jars to ~/.ant/lib .

Resources