In this document, you'll do the following:
In this tutorial, we'll use the Address.xsd file that is in the JaxMe distribution.
A section of this JaxMe schema is shown here:
<?xml version="1.0" encoding="iso-8859-1"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://net/sourceforge/jame/namespaces/examples/Address" xmlns:jm="http://ispsoft.de/namespaces/jaxme/schema"> <xs:annotation> <xs:documentation> A simple JaxMe example: Personal address collection. </xs:documentation> <xs:appinfo> <jm:defaults package="net.sourceforge.jaxme.address"/> </xs:appinfo> </xs:annotation> <xs:element name="Address"> <xs:complexType> <xs:sequence> <xs:element name="Name"> <xs:complexType> <xs:sequence> <xs:element name="First"/> <xs:element name="Middle" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Last"/> <xs:element name="Initials" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Postal"> <xs:complexType> <xs:sequence> <xs:element name="Street"/> <xs:element name="ZIP"/> <xs:element name="City"/> <xs:element name="State" minOccurs="0"/> <xs:element name="Country" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="PhoneDetails" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="Phone" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="PhoneNumber"/> </xs:sequence> <xs:attribute name="type" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="EmailDetails" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="Email" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="EmailAddress"/> </xs:sequence> <xs:attribute name="type" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="id"/> </xs:complexType> </xs:element> </xs:schema>In this tutorial, we'll also be using the following XML document (Address.xml ), which is based on the JaxMe schema Address.xsd.
<?xml version="1.0"?> <Address xmlns="http://net/sourceforge/jaxme/namespaces/examples/Address"> <Name> <First>Jane</First> <Middle>Lee</Middle> <Middle>Chris</Middle> <Last>Doe</Last> <Initials>(JD)</Initials> </Name> <Postal> <Street>34 Main Street</Street> <City>Boston</City> <State>MA</State> <ZIP>02215</ZIP> </Postal> <PhoneDetails> <Phone type="Work"> <PhoneNumber>555.5789</PhoneNumber> </Phone> <Phone type="Fax"> <PhoneNumber>555.1212</PhoneNumber> </Phone> </PhoneDetails> <EmailDetails> <Email type="Private"> <EmailAddress>jdoe@yourcompany.com</EmailAddress> </Email> <Email type="Office"> <EmailAddress>josephdoe@mycompany.com</EmailAddress> </Email> </EmailDetails> </Address>
Run the following commands (assuming bash):
# set to the JaxMe distribution
jaxme=~/JaxMe
java -cp $jaxme/prerequisites/log4j.jar:$jaxme/dist/jaxme.jar
\
de.ispsoft.jaxme.generator.Main
Address.xsd \
--sourceWriter=de.ispsoft.jaxme.generator.JavaSourceWriter
See Building JaxMefor a discussion of the prerequisite jars.
You can use an ant script to run the JaxMe code generator, as described in Writing an ant script.
JavaSourceWriter generates Java sources that are based on the specific JaxMe schema given in this command (Address.xsd). JavaSourceWriter generates a subclass of JMAnyElement and a SAX2 ContentHandler that can parse XMLinstances of the given document type.
Note: When you run the code generator, the specific SourceWriter you choose will depend on your goals. For example, the JdbcJavaSourceWriter is used to read data from or write data to a relational table via JDBC. See Reference and Javadoc for information about currently available SourceWriters.
To view the generated Java code, go to the directory that is specified for package in the JaxMe schema. In this example (the JaxMe schema Address.xsd), the package specified is net/sourceforge/jaxme/address.
<xs:appinfo> <jm:defaults package="com.mycompany.com"/> </xs:appinfo>In this directory, you'll see the generated Java source code, including the following:
As you can see, the contents of a JaxMe schema are mapped to Java member variables. In the above example, the instance of ClsAddress has a variable eName, which holds the details of the name from Address.xsd. The first name is eName.eFirst.
A simple element type in the JaxMe schema is mapped to java.lang.String. For example, ClsName contains public java.lang.String.eFirst. A complex element type in the JaxMe schema is mapped to the next level of Cls*.java. For example, ClsAddress contains ClsName eName.
The variable eName has a type ClsName. However, the type of eEmail is java.util.List. This element may occur multiple times and is used to represent a list of email addresses. The type of ePhone is also java.util.List.
A note about repetition and null values: If minOccurs="0" then the reference may be null. If minOccurs="1" and maxOccurs="1" then the reference will not be null. If maxOccurs is greater than 1, then max will be java.util.List, and if minOccurs=0, then the reference may be null.
Internal members are named according to the following conventions: A JaxMe schema element XXX (such as Postal) is converted to Java member variable eXXX (such as ePostal). An attribute YYY (such as Type) is converted to Java member variable aYYY (such as aType).
In this tutorial, we'll use AddressPrinter.java as our test application (shown below). This application will take Address.xml as input, generate Java objects, and print the data.
JaxMe imports the Java source code that it had generated (see the preceding step in this procedure), instantiates ClsAddress, and uses the JMFileManager to set the SAX ContentHandler for reading elements.
To compile the application, you need to specify the classpath of jaxme-rt.jar; for example (assuming bash):
# set to the JaxMe distribution
jaxme=~/JaxMe
javac -classpath
$jaxme/prerequisites/log4j.jar:$jaxme/dist/jaxme-rt.jar \
-sourcepath
. AddressPrinter.java \
See Building JaxMefor a discussion of the prerequisite jars.
To run the application, you also need to specify the classpath of jaxme-rt.jar:
# set to the JaxMe distribution
jaxme=~/JaxMe
java -classpath
$jaxme/prerequisites/log4j.jar:$jaxme/dist/jaxme-rt.jar \
AddressPrinter \
import net.sourceforge.jaxme.address.ClsAddress; import net.sourceforge.jaxme.address.ClsAddressHandler; import net.sourceforge.jaxme.address.ClsName; import net.sourceforge.jaxme.address.ClsPostal; import net.sourceforge.jaxme.address.ClsPhone; import net.sourceforge.jaxme.address.ClsEmail; import de.ispsoft.jaxme.JMFileManager; public class AddressPrinter { public static void main(String[] args) throws Exception { // Instantiate a JMFileManager and set its SAX content handler // to the generated class ClsAddressHandler. This glues the // reading of an XML input document to the parsing code. JMFileManager manager = new JMFileManager(); manager.setJMContentHandlerClass(ClsAddressHandler.class); // Loop over XML documents within the file. for (java.util.Iterator iter = manager.select("Address.xml"); iter.hasNext(); ) { // Each iteration returns a generic iteration object, // which we must first cast to the generated class // ClsAddress. Then we have access to its internal // members which automatically contain the file's XML // content. ClsAddress ca = (ClsAddress) iter.next(); System.out.println ("eName.eFirst = " + ca.eName.eFirst); if (ca.eName.eMiddle != null) System.out.println ("eName.eMiddle = " + ca.eName.eMiddle); System.out.println ("eName.eLast = " + ca.eName.eLast); if (ca.eName.eInitials != null) System.out.println ("eName.eInitials = " + ca.eName.eInitials); System.out.println ("ePostal.eStreet = " + ca.ePostal.eStreet); System.out.println ("ePostal.eCity = " + ca.ePostal.eCity); System.out.println ("ePostal.eZip = " + ca.ePostal.eZIP); if (ca.ePostal.eState != null) System.out.println ("ePostal.eState = " + ca.ePostal.eState); if (ca.ePostal.eCountry != null) System.out.println ("ePostal.eCountry = " + ca.ePostal.eCountry); if (ca.ePhoneDetails != null) { for (java.util.Iterator phoneIter = ca.ePhoneDetails.ePhone.iterator(); phoneIter.hasNext(); ) { ClsPhone ePhone = (ClsPhone) phoneIter.next(); // Note: aType is a required attribute, so no need // to check for null. System.out.println ("ePhoneDetails.ePhone.aType = " + ePhone.aType); System.out.println ("ePhoneDetails.ePhone.ePhoneNumber = " + ePhone.ePhoneNumber); } } if (ca.eEmailDetails != null) { for (java.util.Iterator eMailIter = ca.eEmailDetails.eEmail.iterator(); eMailIter.hasNext(); ) { ClsEmail eMail = (ClsEmail) eMailIter.next(); // Note: aType is a required attribute, so no need // to check for null. System.out.println ("eMailDetails.eMail.aType = " + eMail.aType); System.out.println ("eMailDetails.eMail.eEmailAddress = " + eMail.eEmailAddress); } } } } }
Again, note that to compile and run the application, you need to specify the classpath of jaxme-rt.jar:
java -classpath prerequisites/log4.jar:dist/jaxme-rt.jar
AddressCreator.java
import net.sourceforge.jaxme.address.ClsAddress;
import net.sourceforge.jaxme.address.ClsEmail;
import net.sourceforge.jaxme.address.ClsEmailDetails;
import net.sourceforge.jaxme.address.ClsName;
import net.sourceforge.jaxme.address.ClsPhone;
import net.sourceforge.jaxme.address.ClsPhoneDetails;
import net.sourceforge.jaxme.address.ClsPostal;
import de.ispsoft.jaxme.JMFileManager;
public class AddressCreator {
public static void main(String args[]) throws Exception {
JMFileManager manager = new JMFileManager();
ClsAddress addr = new ClsAddress();
addr.eName = new ClsName();
addr.eName.eFirst = "Jane";
addr.eName.eLast = "Doe";
addr.ePostal = new ClsPostal();
addr.ePostal.eStreet = "34 Main Street";
addr.ePostal.eCity = "Boston";
addr.ePostal.eState = "MA" ;
addr.ePostal.eZIP = "02215";
addr.eEmailDetails = new ClsEmailDetails();
addr.eEmailDetails.eEmail = new java.util.ArrayList();
ClsEmail email = new ClsEmail();
email.aType = "Private";
email.eEmailAddress = "jdoe@yourcompany.com";
addr.eEmailDetails.eEmail.add(email);
email = new ClsEmail();
email.aType = "Private";
email.eEmailAddress = "josephdoe@mycompany.com";
addr.eEmailDetails.eEmail.add(email);
email = new ClsEmail();
email.aType = "Private";
email.eEmailAddress = "josephdoe@mycompany.com";
addr.eEmailDetails.eEmail.add(email);
addr.ePhoneDetails = new ClsPhoneDetails();
addr.ePhoneDetails.ePhone = new java.util.ArrayList();
ClsPhone ePhone = new ClsPhone();
ePhone.aType = "Work";
ePhone.ePhoneNumber = "555.6789";
addr.ePhoneDetails.ePhone.add(ePhone);
manager.setFileName("AddressOutput.xml");
manager.insert(addr);
}
}
NEXT PREVIOUS TABLE OF CONTENTS