| MAP | SASAX Documents > Parsing with SASAX > Custom element | << | >> |
This section explains that how to create custom element for object un-marshaling from XML document with SAX.
Schema in XML Schema and sample of document is shown in "Document structure", which is as same as ones in the former section.
Schema in XML Schema:
<xs:schema
targetNamespace="http://www.lares.dti.ne.jp/~foozy/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:local="http://www.lares.dti.ne.jp/~foozy/">
<xs:simpleType name="int">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="string">
<xs:restriction base="xs:token"/>
</xs:simpleType>
<xs:element name="composite">
<xs:complexType>
<xs:sequence>
<xs:element name="int" type="local:int"
form="qualified"/>
<xs:element name="string" type="local:string"
minOccurs="0"
form="qualified"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Sample:
<foozy:composite
xmlns:foozy="http://www.lares.dti.ne.jp/~foozy/">
<foozy:int>
12245678
</foozy:int>
<foozy:string>
optional text message
</foozy:string>
</foozy:composite>
Class to parse the document described in the former are defined as shown in "Custom class".
public class CustomElement
extends CompositeElement
{
final private String URI =
"http://www.lares.dti.ne.jp/~foozy/";
final private IntElement int_ =
new IntElement(this, URI, "int");
final private StringElement string_ =
new StringElement(this, URI, "string");
////////////////////////////////////////
public CustomComposite(Element parent){
super(parent, URI, "custom");
addMustItem(int_);
addOptionalItem(string_);
}
}
You can understand above example with the explanation in former sections.
Of course,
you can define "int_"(and "string_") as
"public" for accessing from outer.
It seems to be good idea
because it allows you to separate
"building document structure up"
(= defining CustomElement itself) and
"describing parsing behavior"
(e.g.: adding Notification).
The method to create instance of your custom container from the result of XML document parsing is defined as shown in "CustomContainer creation", for example.
final public CustomContainer getValue(boolean ensure){
if(ensure){ ensureDetermined(); }
// not determined yet
if(!isDetermined()){ return null; }
CustomContainer container = new CustomContainer();
// int_#getInteger MUST return non-null
// because it is registered as MUST ITEM.
container.setInteger(int_.getInteger(false));
// string_#getString MAY return null
// because it is registered as OPTIONAL ITEM.
container.setString(string_.getString(false));
return container;
}
According to
whether element parsing is completed or not,
isDetermined() returns true or false,
and ensureDetermined()
throws nothing or IllegalStateException.
Behavior of getValue is shown below:
| value determination (= isDetermined()) |
"ensure" argument | |
|---|---|---|
| false | true | |
| false | return null | throw exception |
| true | return object | return object |
In this tutorial situation,
you should specify "false" as ensure argument
only when you (1)already ensure determination of target
or (2)allow it to return null.
getInteger or getString methods are invoked with
"false" as "ensure" argument
both on int_ and string_,
but their meanings are not same.
int_.getInteger() is invoked with "false"
to skip determination check,
because it, as MUST ITEM, must have same determination of
CustomElement,
and it is ensured already.
string_.getString() is invoked with "false"
(a)to skip determination check
because it, as OPTIONAL ITEM, may not be determined
(and causes exception raising with "true" argument), and
(b)to get null when it is not determined.
You must check determination of string_
and invoke CustomContainer#setString(),
if that method does not allow null argument.
You can parse XML document by the code shown in "Parse document" as you know.
CustomElement customElement = new CustomElement(null);
try{
ElementDrivenHandler handler =
new ElementDrivenHandler(customElement);
handler.parse(reader);
// Determination is ensured here,
// so you can specify "false" to "getValue" safely.
CustomContainer container = customElement.getValue(true);
// process around container here ....
}
catch(Exception e){
// below will cause exception raising
customElement.getValue(true);
// below will return null
customElement.getValue(false);
}
Complete code for this tutorial section is
jp.ne.dti.lares.foozy.sasax.CustomDemo
under src/demo/sasax/src in distribution.
This class is included in demo.jar of binary distribution.
Please see "Detailed information" of "Composite element" section.
| MAP | SASAX Documents > Parsing with SASAX > Custom element | << | >> |