Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

XML Pipelining with Ant
by Michael Fitzgerald | Pages: 1, 2

Validating with Jing

As I mentioned earlier, Ant is extensible. One way that you can extend Ant is by writing your own task ( instructions on how to do this are found in the Ant manual). James Clark has written a task for Jing that allows you to use Ant to validate XML documents against RELAX NG schemas, in both XML and compact syntaxes. Jing's source code is available for download, but for convenience I have included a copy of JingTask.java in the example archive for easy inspection (along with a copy of Jing's license).

The document date.xml is valid with regard to the RELAX NG schema date.rng:

<?xml version="1.0"?>

<element name="date" xmlns="http://relaxng.org/ns/structure/1.0"
 datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 <data type="dateTime"/>
</element>

RELAX NG supports externally defined datatype libraries, such as W3C XML Schema datatypes. The XML Schema datatype dataTime more precisely defines the valid content of <date> than just #PCDATA in a DTD. To validate date.xml against date.rng with Ant, use the build file build-jing.xml:

<?xml version="1.0"?>

<project default="rng">

 <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask"/>

 <target name="rng">
  <echo message="Validating RELAX NG schema with Jing..."/>
  <jing rngfile="date.rng" file="date.xml"/>
 </target>

</project>

The <taskdef> element defines the jing task, and its classname attribute identifies the class that executes the task. This class is stored in jing.jar, part of the Jing distribution. If you place jing.jar in Ant's lib directory, Ant will be able to find the Jing task.

The echo task echoes the text in message. Jing is silent upon success, as are other tasks. You can throw in an echo task to augment what is normally reported.

The jing task's rngfile identifies a RELAX NG schema, and the file attribute names the instance of the schema. You can also use a fileset type as a child of <jing>, allowing you to validate more than one document at a time.

Jing can also validate against schemas in the compact syntax, RELAX NG's terse, non-XML format. The compact version reduces date.rng to one short line in date.rnc:

element date { xsd:dateTime }

Compact syntax processors automatically declare the XML Schema datatype library with the xsd prefix. The build file build-rnc.xml validates date.xml against date.rnc (note the addition of the compactsyntax attribute):

<?xml version="1.0"?>

<project default="rng">

 <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask"/>

 <target name="rng">
  <echo message="Validating RELAX NG compact syntax schema with Jing..."/>
  <jing compactsyntax="true" rngfile="date.rnc" file="date.xml"/>
 </target>

</project>

Kawaguchi Kohsuke is currently developing an Ant task for validators that support the Java API for Relax Verifiers (JARV). This task will work with Sun's Multi-schema Validator and other JARV validators.

An XML Pipeline Example

This example places targets discussed earlier together into a single build file and adds a few other targets as well. The resulting file, build.xml, is an example of a simple XML pipeline. The basic scenario is that a property is set (the current directory) using a local XML document (properties.xml) and a remote, zipped file (date.zip) is downloaded via the get task. The file, which contains a RELAX NG schema (date.rng), is unzipped and a local document (date.xml) is validated against it. Then the same document is validated against a DTD (date.dtd) and transformed into an HTML document (date.html). Finally, an e-mail is sent, signaling the completion of the process. Granted, this is a rather uncomplicated example, and more complex operations are possible, but this gives you an idea of how you can put your own pipeline together.

Here is the build file:

<?xml version="1.0"?>

<project default="mail">

 <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask"/>

 <target name="init">
  <echo message="Load XML properties..."/>
  <xmlproperty file="properties.xml"/>
 </target>

 <target name="get" depends="init">
  <get src="http://www.wyeast.net/date.zip" dest="date.zip"/>
 </target>

 <target name="unzip" depends="get">
  <unzip src="date.zip" dest="${build.dir}"/>
 </target>

 <target name="rng" depends="unzip">
  <echo message="Jing validating..."/>
  <jing rngfile="date.rng" file="date.xml"/>
 </target>

 <target name="val" depends="rng">
  <xmlvalidate file="date.xml">
   <xmlcatalog>
    <dtd publicId="-//Wy'east Communications//Date DTD//EN"
    location="date.dtd"/>
   </xmlcatalog>
  </xmlvalidate>
 </target>

 <target name="xform" depends="val">
  <xslt in="date.xml" out="date.html"
      style="date.xsl">
   <outputproperty name="method" value="xml"/>
   <outputproperty name="indent" value="yes"/>
  </xslt>
 </target>

 <target name="mail" depends="xform">
  <mail mailhost="mail.example.com" subject="Ant build">
   <to address="schlomo@example.com"/>
   <from address="hermes@example.com"/>
   <message>Complete!</message>
  </mail>
 </target>

</project>

Before running this example, you should change the values of mailhost and both the to and from addresses to something that will work on your own mail server. You will also need to install the JAR files from the JavaMail project in Ant's lib directory (though MIME mail may still not work). To run the build, all you have to do is type:

C:\Java\Ant>ant

Because the build file is named build.xml, Ant automatically picks it up and runs it. The output will look like this, provided you have a live Internet connection (for the get and mail targets), and all files from the example archive are still in place:

Buildfile: build.xml

init:
     [echo] Load XML properties...

get:
      [get] Getting: http://www.wyeast.net/date.zip

unzip:
    [unzip] Expanding: C:\Java\Ant\date.zip into C:\Java\Ant

rng:
     [echo] Jing validating...

val:
[xmlvalidate] 1 file(s) have been successfully validated.

xform:
     [xslt] Processing C:\Java\Ant\date.xml to C:\Java\Ant\date.html
     [xslt] Loading stylesheet C:\Java\Ant\date.xsl

mail:
     [mail] Failed to initialise MIME mail
     [mail] Sending email: Ant build
     [mail] Sent email with 0 attachments

BUILD SUCCESSFUL
Total time: 7 seconds

Each of the targets except the one named init has a depends attribute. The value of this attribute establishes a hierarchy of dependencies between the targets. The default or starting target is mail (identified in the <project> element); in order for it to execute, the xform target must first execute successfully and in order for xform to execute, val must execute, and so forth. So this dependency is not established structurally, as through a parent-child relationship, but rather through attribute values. You can put the targets in any order in the build file. They will be still execute according to the order of the values in the depends and name attributes. These dependencies make up the segments of the pipeline.

The build file has an xslt target that transforms date.xml into date.html according to the XSLT stylesheet date.xsl. The <outputproperty> children contribute values that would normally be supplied by the output element of XSLT. (Tony Coates' article deals with the xslt target extensively, so I'll limit my comments here.)

The xmlvalidate target uses the xmlcatalog type with a <dtd> child to specify a formal public identifier for a DTD and the location of a local copy of that DTD. This type is based on the XML Catalog specification, an entity and URI resolution initiative from OASIS.

The get target gets a URL source, downloading it to a specified location. The xmlproperty target reads the file properties.xml:

<?xml version="1.0"?>

<build>
 <dir>.</dir>
</build>

The arbitrary tags in the properties file determine the name or names for the variable that you can use elsewhere in the build file to reference values, such as ${build.dir}. The first part of the variable name comes from the <build> tag and the second part from <dir>. The content of <dir> becomes the value of the variable. You can also use attributes to create property names.

Running XmlLogger

Ant provides logging and event listening facilities. One such logger-listener is defined in the class org.apache.tools.ant.XmlLogger, which produces XML output. The following command line puts the XML logger to work:

C:\Java\Ant>ant -logger org.apache.tools.ant.XmlLogger -v -l log.xml

The -v (or -verbose) option indicates verbose output, all of which is sent to the log file; the -l option (or -logfile) provides a name for the log file. You can find an XSLT stylesheet for log files in the etc directory called log.xsl. The following figure shows you how log.xml will appear in a browser after it has been transformed by log.xsl.

log.xml
log.xml after being transformed by log.xsl

Conclusion

I realize that Ant was not intended to be a an XML pipeline tool, but it turns out to be a pretty good one anyway. Other tools exist and may eventually do a better job, such as Sean McGrath's XPipes or Eric van der Vlist's XML Validation Interoperability Framework (XVIF). For now, though, Ant remains an attractive option. Like XML, Ant can do things that perhaps it was not originally intended to do. That's a good sign.


Comment on this articleShare your comments or questions on this article in our forum.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • parse XML file in ANT Script
    2009-06-21 10:59:46 Binod Suman [Reply]

    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


    Thanks,


    Binod Suman
    http://binodsuman.blogspot.com/2009/06/how-to-parse-xml-file-in-ant-script.html

  • tasks to generate XML dynamically
    2003-03-11 03:37:29 Martin Klang [Reply]

    for those interested, here are two more XML tools that can be used as ant tasks :


    - o:XML (http://www.o-xml.org) object-oriented programming language with XML syntax.


    - TagBox (http://sourceforge.net/projects/tagbox) extensible 'active' XML tags that facilitate access to db's and other sources of data.


    They both focus on generating and processing XML rather than validation or presentation/transformation. The combination of one or both of these tools together with Schema validation and/or XSLT can be very powerful in a web publishing or content creation / content managment system.

  • Try Jelly and get the best of both worlds: Ant tasks and true XML Pipelining
    2003-03-04 23:34:17 James Strachan [Reply]

    Jelly was designed for XML pipelining


    http://jakarta.apache.org/commons/jelly/pipeline.html


    Jelly has full support for Ant tasks so you can combine all the Ant tasks you know and love with a true XML pipelining architecture.


    Both DOM, SAX and bean style pipelining are supported.


    With Jelly there's no need to write out each step in the pipeline and then reparse the output again in the next pipeline step (which isn't very efficient) you can literally pipeline SAX events through arbitrarily complex pipelines.


    Each Tag in Jelly can filter, transform, generate or consume XML events. Coupled with Jelly's support of expression languages like XPath and Jexl together with scripting language support like BeanShell, JavaScript, Jython, this leads to a powerful & clean XML pipelining tool.

  • Ant vs. dedicated XML pipeline tools
    2003-01-31 03:50:56 Anthony Coates [Reply]

    It's worth restating that because Ant is a general purpose tool, and not a dedicated XML pipeline tool, it can do various housekeeping tasks (e.g. moving or deleting files) which are related to your XML pipeline, but unlikely to be implemenented in a dedicated pipeline tool. It makes Ant a real time-saver for me in practice.


    That said, it would be interesting to see XPipe or similar implemented as an Ant task, so that you could have the best of both worlds.


    Cheers, Tony.

  • more XML tasks
    2003-01-30 17:19:58 Steve Loughran [Reply]

    Can I point people to the external task, Styler, which is a more serious XML pipeline in ant than the xslt task -see http://www.langdale.com.au/styler/.


    Also, the xmlvalidate task in ant 1.6 will be Xml Schema aware, which is a good or bad thing, depending upon your beliefs. We are still having fun with catalog resolution for Schema, so if anyone wants to muck in and help, download the CVS tree and get coding!


    Steve Loughran





  • mail support.
    2003-01-30 17:16:40 Steve Loughran [Reply]

    um, the reason mime mail doesnt work is that you need activation.jar in ant lib too. And if you just want to send plain text, rather than mime stuff, you dont need any jars at all, as Ant builds basic smtp support in.


    Steve 'Java Development with Ant' Loughran.