views:

1086

answers:

4

Is there an Ant API for reading and ant build.xml and retrieving elements from it? Specifically I want to be able to retrieve the values in a path element and be able to walk all of the elements in the path.

My purpose is to retrieve a given path and ensure that it is referenced correctly in a manifest, so that the build and the manifest match when the product goes out to production.

EDIT: Regarding the responses (and thank you for them) to use an XML API, the problem is that the build file as currently constructed is more complex than that. Namely the classpath references a different classpath and includes it and the elements referenced in the classpath are themselves defined in a properties file, so there is too much of the Ant API to reasonably recreate.

+1  A: 

I don't think there's an API available, but as you are only interested in one specific element, you could just write a script that only pulls out the path element and checks them over. A SAX parser in python should be fairly easy to do this with.

from xml.sax import make_parser
from xml.sax.handler import ContentHandler 

def PathHandler(ContentHandler):
    def __init__(self):
        self._reading_path = False
        self._path = ""

    def start_element(self, name, attrs):
        if name == "path":
            self._reading_path = True

    def characters(self, ch):
        if self._reading_path:
            self._path += ch

    def end_element(self, name):
        if name == "path":
            self._reading_path = False
            #self._path is now populated with the contents of the path element

    @property
    def path(self):
        return self._path

handler = PathHandler()
parser = make_parser()
parser.setContentHandler(handler)
parser.parse("build.xml")

This would read any text nodes that are between two xml elements. It should be fairly easy to customise to fulfil other simple XML parsing requirements.

workmad3
A: 

If you only want to retrieve a special element, use the Java XML API.

Mork0075
+3  A: 

You can use the ProjectHelper class to configure your project with a buildfile. If the path you want to check is contained in a reference, then you can just get the reference from the project by its ID.

For example, if you have something like this in your build.xml:

<path id="classpath">
    <fileset dir="${basedir}/lib" includes="*.jar"/>
</path>

Then you can get the Path reference with the following code:

import java.io.File;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.types.Path;

public class Test {
    public static void main(String[] args) throws Exception {    
        Project project = new Project();
        File buildFile = new File("build.xml");
        project.init();
        ProjectHelper.configureProject(project, buildFile);

        Path path = (Path) project.getReference("classpath");
     }
}

Note that ProjectHelper.configureProject is deprecated in ant 1.6.2, but not in 1.7.

Jason Day
Very cool, thanks!
Yishai
+1  A: 

Some time we need to parse xml file in Ant script to run the java file or read some property value and more like this. It is very easy, we can do this with tag called <xmlproperty>. This tag loads the xml file and it convert all the values of xml file in ant property value internally and we can use those value as ant property. For example

<root>
    <properties>
      <foo>bar</foo>
    </properties>
</root>

is roughly equivalent to this into ant script file as: <property name="root.properties.foo" value="bar"/> and you can print this value with ${root.properties.foo}.

Complete Example: 1. Create one xml file say Info.xml 2. Create one ant script say Check.xml

Info.xml

<?xml version="1.0" encoding="UTF-8"?>
<Students>

  <Student>
    <name>Binod Kumar Suman</name>
        <roll>110</roll>
    <city> Bangalore </city>
  </Student>


</Students>

Check.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="Check" default="init">
 <xmlproperty file="Info.xml" collapseAttributes="true"/>

<target name = "init">
  <echo> Student Name :: ${Students.Student.name} </echo>
  <echo> Roll :: ${Students.Student.roll} </echo>
  <echo> City :: ${Students.Student.city} </echo>
</target>

</project>

Now after run this (Check.xml) ant script, you will get output

Buildfile: C:\XML_ANT_Workspace\XML_ANT\src\Check.xml init: [echo] Student Name :: Binod Kumar Suman [echo] Roll :: 110 [echo] City :: Bangalore BUILD SUCCESSFUL Total time: 125 milliseconds

It was very simple upto here, but if you have multiple records in xml (StudentsInfo.xml) then it will show all record with comma seperated like this

Buildfile: C:\XML_ANT_Workspace\XML_ANT\src\Check.xml init: [echo] Student Name :: Binod Kumar Suman,Pramod Modi,Manish Kumar [echo] Roll :: 110,120,130 [echo] City :: Bangalore,Japan,Patna BUILD SUCCESSFUL Total time: 109 milliseconds

Link