Start with Java
Basic Marshalling and Unmarshalling
When starting with Java, a developer should be able to do the following:
1. Write a plain old Java class, possibly (but totally optionally) with special annotations.
MyRecord.java:
{{{ package com.mycompany;
class MyRecord {
- private String ticker; private int shares; public String getTicker() { return ticker; } public void setTicker(String ticker) { this.ticker = ticker; } public int getShares() { return shares; } public void setShares(int shares) { this.shares = shares; }
2. Compile the Java class with the binding compiler:
> xbj2s com/mycompany/MyRecord.java Generating schema... Generating binding... Compiling java... Compiled type library to xmltypes.jar
3. Write a program to use the given types via XmlBeans.unmarshal and XmlBeans.marshal.
class MyTest
{
public static void main(String[] args)
{
Object result = org.apache.xmlbeans.XmlBeans.unmarshal(new File(args[1]));
com.mycompany.MyRecord myRecord = (MyRecord)result;
// the following does not actually serialize the xml until it is pulled
XmlObject xml = org.apache.xmlbeans.XmlBeans.marshal(result);
System.out.println(xml); // for example, printing the XML pulls it
}
} 4. Compile and use the program with the xmltypes.jar on the classpath.
Use as a "convenience type" within a bound XML infoset
1. Write a schema that refers to the previously generated schema types.
{{{ <xs:schema ...>
<xs:element name="bundle">
<xs:complexType>
<xs:sequence>
<xs:element name="item" type="myco:MyRecord"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema> }}}
2. Compile the schema into bound XMLBeans.
> scomp bundle.xsd
3. Use the compiled schema within your app
{{{ BundleDocument.Bundle bundle = BundleDocument.parse(myFile).getBundle();
MyRecord[] records = bundle.getItemArray(); for (int i = 0; i < records.length; i++)
- System.out.println(records[i].getTicker());
- }}}
4. When changing the data, remember to write it back to the closest XML container
{{{ records[i].setTicker("MSFT");
- bundle.setItem(i, records[i]); }}}
5. To check that things are in sync, use the "verify" method
{{{ if (!bundle.verify())
- System.out.println("You forgot to write your changes back into the XML"); }}}
User Model
Every schema type has:
{{{ 1. An optional "exact" formal class.
- Not every schema type has a formal Java class, but all the built-in ones do, and every schema type that has been compiled in XMLBeans style does.
- A "declarable" formal class.
This is what the type would formally be declared as, e.g., XmlObject. It is the closest "formal" type after following the base class chain.
- An optional "preferred" convenience class.
- This is the class that it is assumed the user would prefer to work with when encountering instances of this schema type. all user-defined simple-content types are typically filled in. anyType must be left empty.
- A set of "possible" convenience classes.
- These are the types that can be converted to+from the given schema type. }}}
Every Java class has:
{{{ 1. Optionally, a corresponding schema type.
- Optionally, a corresponding global schema element.
- Optionally, a corresponding global schema attribute. }}}
Every property has:
{{{ 1. A "declared" class
- May be hand-selected by the user. The default algorithm for autopicking one is:
- First, parent container wins.
- If there is an exact "preferred" convenience class, use it.
- Otherwise, pick the "declarable" formal class.
- A "substitution" rule.
- May be hand-picked by the user. The default substitution rule is: - If convenience type, then
schema->java: use the "preferred" convenience class of the closest
- base class that produces a convenience class that inherits from the declared class; if none, then error.
java->schema: if the "corresponding" schema type is less specific, then
- keept the default; if more specific, substitute; if unrelated, then error.
schema->java: use the "closest" formal type corresponding to the instance java->schema: the schema type is part of the instance data (xobj.schemaType()).
- A hand-written substitution rule has:
- An algorithm.
- Given access to the binding type loader....
schema->java: given the elt/attr name and the schema type,
- and the declared java class, produces a binding type name for the substitution.
java->schema: given the Class object and the declared schema type,
- elt/attr (or none for wildcards, etc...), produces a binding type name for the substitution.
- }}}
- Given access to the binding type loader....
- An algorithm.
- May be hand-picked by the user. The default substitution rule is: - If convenience type, then