Home of: [Atelier "FUJIGURUMA"] >> [SASAX hosted by SourceForge.net]

SEE "For Readers of English Version",
or Japanese version of this page

Custom element

This section explains that how to create custom element for object un-marshaling from XML document with SAX.

Define document structure

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>

Document structure

Create element object(s)

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_);
    }
}

Custom class

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).

Ensure determination

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;
    }

CustomContainer creation

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.

Parse document

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);
}

Parse document

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.


To next section "Element choice"

Detailed information

Please see "Detailed information" of "Composite element" section.