MAP | SASAX Documents > Parsing with SASAX > 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.
xsi:nil
sensitivelyAccording 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);
Then, above "element
" can accept
<int xsi:nil="true"/>
,
even though "empty text" does not satisfy "int" restriction.
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/>
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);
Above element
can accept "<int/>
",
even though it does not have xsi:nil="true"
attribute.
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>
"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 */ } } });
By the way,
using "addOptionalItem()
" instead of
"addMustItem()
" allows you to
ignore(or detect) incomplete "<entry>
".
In this tutorial, abbreviated class names are used. Complete names are shown below.
Notation | Full 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 |
MAP | SASAX Documents > Parsing with SASAX > | << | >> |