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

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

Validation control

This section explains how to control validation process of SASAX ValueElement(and classes derived from it).

Topics of this section are:

ATTENTION: features explained in this section are available since SASAX 1.5.

Parse xsi:nil sensitively

According to XML Schema specification, when (1) nillable="true" is described in XML Schema and (2) xsi:nil="true" is described in XML document, such element should be empty in XML document.

ValueElement provides setNillable(boolean) method which correspond to nillable attribute description in XML Schema.


IntElement element = new IntElement(parent, null, "int");
element.setNillable(true);

Allow 'xsi:nil="true"' attribute

Then, above "element" can accept <int xsi:nil="true"/>, even though "empty text" does not satisfy "int" restriction.

Skip validation process for empty text

NOTE: the feature explained here is not required, if you want to accept only valid XML document.

In many development scenes, at least for me, ignoreing some invalid parts of document (or detecting them out) is required to continue processing on the rest of document, even though the XML schema on which both document "generator" and "consumer" agree does not allow such document.

As described in before sub section, you can get the ValueElement object, which can accept empty text, by "setNillable(true)". But it only allows the elements with xsi:nil="true" attribute to be empty.


Acceptable document:

    <int xsi:nil="true"/>

Unacceptable document:

    <int/>

Acceptance of "nillable" element

In fact, it depends on type specific validation whether empty text is acceptable or not.

For example, "StringElement" can accept empty text even though it does not have xsi:nil="true" attribute, because "empty text" is also "string". On the other hand, "DateTimeElement" (and many of classes derived from ValueElement) rejects it because "empty text" does not satisfy "date time" restriction.

So, ValueElement now provides "setIgnoreEmpty(true)" method to specify skipping validation process for empty text. For example:


IntElement element = new IntElement(parent, null, "int");
element.setIgnoreEmpty(true);

Skip validation on empty text

Above element can accept "<int/>", even though it does not have xsi:nil="true" attribute.

Delay validation process

NOTE: the feature explained here is not required, if you want to accept only valid XML document.

In many development scenes, at least for me, ignoreing some invalid parts of document (or detecting them out) is required to continue processing on the rest of document, even though the XML schema on which both document "generator" and "consumer" agree does not allow such document.

ValueElement validates described text as soon as receiving "endElement" SAX event (= at the end of corresponded tag). But such immediateness prevents you from continuing document processing without invalid elements. For example:


<entry name="1">
  <int>abcd</int> <!-- invalid "int" -->
  <date>2006-12-31</date>
</entry>
<entry name="2">
  <int>1234</int>
  <date>2006/12/31</date> <!-- invalid "date" -->
</entry>
<entry name="3">
  <int>1234</int>
  <date>2006-12-31</date>
</entry>

The document containing invalid parts

"Immediate validation" throws SAXException at the end of int element of name="1" entry, and such throwing does not allow continuation of document parsing. So it is not good for the situation that you want to process valid entries(name="3", in this case) and to log information about other invalid entries.

You can prevent ValueElement from "validating described text at the end of element" by "setDelayed(true)" invocation.

This invocation delays validation process until explicit "validate()" invocation. So you can ignore(or detect) invalid "<entry>" by code shown below.


CompositeElement entry = 
    new CompositeElement(parent, null, "entry");

final
IntElement intElement = 
    new IntElement(entry, null, "int");
intElement.setDelayed(true);
entry.addMustItem(intElement);

final
DateElement dateElement = 
    new DateElement(entry, null, "date", ....);
dateElement.setDelayed(true);
entry.addMustItem(dateElement);

entry.addNotification(new Notification(){
    public void elementStarted(Element element,
                               ParseContext context,
                               Attributes attributes)
    { /* nop */ }

    public void elementEnded(Element element,
                             ParseContext context)
    {
        try{
            Integer intValue = 
            (Integer)(intElement.validate(context, false));
            // above invocates "delayed" validation

            Date dateValue =
            (Date)(dateElement.validate(context, false));
            // above invocates "delayed" validation

            /* your custom processing is placed here ..... */
        }
        catch(Exception e){
            /* log validation error detail */
        }
    }
});

ignore invalid entries

By the way, using "addOptionalItem()" instead of "addMustItem()" allows you to ignore(or detect) incomplete "<entry>".


To next section "Path handling"

Detailed information

Class names

In this tutorial, abbreviated class names are used. Complete names are shown below.

NotationFull name
CompositeElement jp.ne.dti.lares.foozy.sasax.CompositeElement
DateElement jp.ne.dti.lares.foozy.sasax.DateElement
Element jp.ne.dti.lares.foozy.sasax.Element
IntElement jp.ne.dti.lares.foozy.sasax.IntElement
Notification jp.ne.dti.lares.foozy.sasax.Notification
ParseContext jp.ne.dti.lares.foozy.sasax.ParseContext
StringElement jp.ne.dti.lares.foozy.sasax.StringElement
ValueElement jp.ne.dti.lares.foozy.sasax.ValueElement