Working with XML documents
In this section, you'll learn about running the JiBX binding compiler and using JiBX at run time to work with XML documents.
Running the JiBX binding compiler
To use the generated binding definition in working with XML documents, you first
need to run the JiBX binding compiler. The binding compiler adds bytecode to your
compiled class files that actually implements the conversions to and from XML, as
specified by the binding definition. You must run the binding compiler each time you
recompile your Java classes or modify the binding definition, so it's usually best to
add the binding-compiler step as part of your project's standard build process.
The binding compiler is included in the JiBX distribution as part of jibx-bind.jar. The JiBX documentation provides full details about different ways to run the binding compiler, including how you can invoke it when running your application rather than as part of the build. JiBX also provides plug-ins for Eclipse and IntelliJ IDEA that automatically run the binding compiler when you're working in these IDEs.
For this tutorial's purposes, you'll keep things simple and just run the binding compiler through Ant. The build.xml's compile target prepares for the binding by compiling both the generated code and a supplied test program, while the bind target actually runs the binding compiler. Figure 2 shows the output that you should see when you run these targets, assuming you've already run the codegen targets. (You can also run all three targets in sequence by listing them in order on the command line: ant codegen compile bind.)
Figure 2. Ant build compile and bind tasks
Using JiBX at run time
Listing 3 shows a simple test document matching the schema, included in the tutorial's code download as starter.xml:
Listing 3. Test document for order schema
<order orderDate="2008-10-18" shipDate="2008-10-22" xmlns="http://jibx.org/starter">
<orderNumber>12345678</orderNumber>
<customer>
<customerNumber>5678</customerNumber>
<firstName>John</firstName>
<lastName>Smith</lastName>
</customer>
<billTo state="WA" postCode="98059">
<street1>12345 Happy Lane</street1>
<city>Plunk</city>
<country>USA</country>
</billTo>
<shipping>PRIORITY_MAIL</shipping>
<shipTo state="WA" postCode="98034">
<street1>333 River Avenue</street1>
<city>Kirkland</city>
</shipTo>
<item quantity="1" price="5.99" id="FA9498349851"/>
<item quantity="2" price="9.50" id="GC1234905049"/>
<item quantity="1" price="8.95" id="AX9300048820"/>
</order> |
The download package also includes a simple test program, shown here as Listing 4, that demonstrates using JiBX for both unmarshalling and marshalling documents. Marshalling is the process of generating an XML representation for an object in memory, potentially including objects linked from the original object. Unmarshalling is the reverse process of marshalling, building an object (and potentially a graph of linked objects) in memory from an XML representation. The Ant run target executes this test program, using the Listing 3 document as input and writing the marshalled copy of the document to a file named out.xml.
Listing 4. Test program
public class Test
{
/**
* Unmarshal the sample document from a file, compute and set order total, then
* marshal it back out to another file.
*
* @param args
*/
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: java -cp ... " +
"org.jibx.starter.Test in-file out-file");
System.exit(0);
}
try {
// unmarshal customer information from file
IBindingFactory bfact = BindingDirectory.getFactory(Order.class);
IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
FileInputStream in = new FileInputStream(args[0]);
Order order = (Order)uctx.unmarshalDocument(in, null);
// compute the total amount of the order
float total = 0.0f;
for (Iterator<Item> iter = order.getItems().iterator(); iter.hasNext();) {
Item item = iter.next();
total += item.getPrice() * item.getQuantity();
}
order.setTotal(new Float(total));
// marshal object back out to file (with nice indentation, as UTF-8)
IMarshallingContext mctx = bfact.createMarshallingContext();
mctx.setIndent(2);
FileOutputStream out = new FileOutputStream(args[1]);
mctx.setOutput(out, null);
mctx.marshalDocument(order);
System.out.println("Processed order with " + order.getItems().size() +
" items and total value " + total);
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(1);
} catch (JiBXException e) {
e.printStackTrace();
System.exit(1);
}
}
} |
Figure 3 shows the output you should see when you run the run target:
Figure 3. Ant build run task
This is the same test program as used in Part 1, and it's subject to the same limitations discussed in that tutorial. Just as in Part 1, the out.xml file has the output generated by marshalling back out the order data that was obtained by unmarshalling the original document.
|