blob: 6472183ddda14536c29561a74fc3437dd8f20cb6 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package drtcases;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.impl.store.Root;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XMLStreamValidationException;
import org.apache.xmlbeans.XmlDecimal;
import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import weblogic.xml.stream.XMLInputStream;
import javax.xml.namespace.QName;
public class ValidationTests extends TestCase
{
public ValidationTests(String name) { super(name); }
public static Test suite() { return new TestSuite(ValidationTests.class); }
static String[] _args;
static String _test;
public static File getCaseFile(String theCase)
{
return TestEnv.xbeanCase("store/" + theCase);
}
static XmlCursor loadCase(String theCase) throws Exception
{
return
XmlObject.Factory.parse(
getCaseFile( theCase ) ).newCursor();
}
public SchemaTypeLoader makeSchemaTypeLoader ( String[] schemas )
throws Exception
{
XmlObject[] schemaDocs = new XmlObject [ schemas.length ];
for ( int i = 0 ; i < schemas.length ; i++ )
{
schemaDocs[ i ] =
XmlObject.Factory.parse(
schemas[ i ] );
}
return XmlBeans.loadXsd( schemaDocs );
}
public SchemaTypeLoader makeSchemaTypeLoader ( File[] schemas )
throws Exception
{
XmlObject[] schemaDocs = new XmlObject [ schemas.length ];
for ( int i = 0 ; i < schemas.length ; i++ )
{
schemaDocs[ i ] =
XmlObject.Factory.parse(
schemas[ i ], new XmlOptions().setLoadLineNumbers().setLoadMessageDigest() );
}
return XmlBeans.loadXsd( schemaDocs );
}
public void v ( String xml ) throws Exception
{
XmlObject x = XmlObject.Factory.parse( xml );
Assert.assertTrue( x.schemaType() != XmlObject.type );
Assert.assertTrue( x.validate() );
}
public void nv ( String xml ) throws Exception
{
XmlObject x = XmlObject.Factory.parse( xml );
Assert.assertTrue( x.schemaType() != XmlObject.type );
Assert.assertTrue( !x.validate() );
}
public void ___testDefault ( ) throws Exception
{
// Default
// v( "<validElemDefault/>" );
// v( "<validAttrDefault/>" );
//
// nv( "<invalidElemDefault/>" );
nv( "<invalidAttrDefault/>" );
v( "<invalidElemDefault>11<invalidElemDefault>" );
v( "<invalidAttrDefault attr='22'>" );
// Fixed
v( "<validElemFixed/>" );
v( "<validAttrFixed/>" );
nv( "<invalidElemFixed/>" );
nv( "<invalidAttrFixed/>" );
v( "<invalidElemFixed>33<invalidElemFixed>" );
v( "<invalidAttrFixed attr='44'/>" );
}
public void doTest (
String[] schemas, QName docType,
String[] validInstances, String[] invalidInstances)
throws Exception
{
doTest(schemas, docType, validInstances, invalidInstances, true);
}
public void doTest (
String[] schemas, QName docType,
String[] validInstances, String[] invalidInstances, boolean startOnDocument )
throws Exception
{
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
XmlOptions options = new XmlOptions();
if (docType != null)
{
SchemaType docSchema = stl.findDocumentType( docType );
Assert.assertTrue( docSchema != null );
options.put( XmlOptions.DOCUMENT_TYPE, docSchema );
}
for ( int i = 0 ; i < validInstances.length ; i++ )
{
XmlObject x =
stl.parse( (String) validInstances[ i ], null, options );
if (!startOnDocument)
{
XmlCursor c = x.newCursor();
c.toFirstChild();
x = c.getObject();
c.dispose();
}
List xel = new ArrayList();
options.put( XmlOptions.ERROR_LISTENER, xel );
boolean isValid = x.validate( options );
if (!isValid)
{
System.err.println( "Invalid doc, expected a valid doc: " );
System.err.println( "Instance(" + i + "): " );
System.err.println( x.xmlText() );
Root.dump( x );
System.err.println( "Errors: " );
for ( int j = 0 ; j < xel.size() ; j++ )
System.err.println( xel.get( j ) );
System.err.println();
}
Assert.assertTrue( isValid );
}
for ( int i = 0 ; i < invalidInstances.length ; i++ )
{
XmlObject x;
try
{
x = stl.parse( (String) invalidInstances[ i ], null, options );
if (! startOnDocument)
{
XmlCursor c = x.newCursor();
c.toFirstChild();
x = c.getObject();
c.dispose();
}
boolean isValid = x.validate();
if (isValid)
{
System.err.println( "Valid doc, expected a invalid doc: " );
System.err.println( "Instance(" + i + "): " );
System.err.println( x.xmlText() );
Root.dump( x );
System.err.println();
}
Assert.assertTrue( !isValid );
}
catch ( XmlException e )
{
}
}
}
// Just compile a schema, good and bad
public void testValidate0 ( )
throws Exception
{
//
// The most basic schema
//
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
"</xs:schema>" +
"";
String[] schemas = { schema };
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
//
// One which uses ##targetNamespace on a wildcard
//
schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
" <xs:complexType name='foo'>\n" +
" <xs:sequence>\n" +
" <xs:any namespace='##targetNamespace'/>\n" +
" </xs:sequence>\n" +
" </xs:complexType>\n" +
"</xs:schema>" +
"";
String[] schemas99 = { schema };
stl = makeSchemaTypeLoader( schemas99 );
//
// A big, nasty schema :-)
//
File file = TestEnv.getRootFile();
File schemeFile = new File( file, "test/cases/schema/s4s/XMLSchema.xsd" );
File xmlFile = new File( file, "test/cases/schema/s4s/XML.xsd" );
File[] schemasF = { schemeFile, xmlFile };
Root.disableStoreValidation();
try
{
stl = makeSchemaTypeLoader( schemasF );
}
finally
{
Root.enableStoreValidation();
}
SchemaType type =
stl.findDocumentType(
new QName( "http://www.w3.org/2001/XMLSchema", "schema" ) );
Assert.assertTrue( type != null );
//
// A good piece from a J2EE schema
//
schema =
"<?xml version='1.0' encoding='UTF-8'?>\n" +
"<xsd:schema xmlns='http://www.w3.org/2001/XMLSchema'\n" +
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n" +
" elementFormDefault='qualified'\n" +
" attributeFormDefault='unqualified'>\n" +
"<xsd:annotation>\n" +
"<xsd:documentation>\n" +
"@(#)application-client_1_4.xsds 1.7 07/08/02\n" +
"</xsd:documentation>\n" +
"</xsd:annotation>\n" +
"</xsd:schema>\n";
String[] schemas5 = { schema };
stl = makeSchemaTypeLoader( schemas5 );
//
// A bad schema
//
schema = "<foo/>";
String[] schemas2 = { schema };
try
{
stl = makeSchemaTypeLoader( schemas2 );
Assert.assertTrue( false );
}
catch ( Exception e )
{
}
//
// A bad schema
//
schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
" <foo/>\n" +
"</xs:schema>" +
"";
String[] schemas3 = { schema };
try
{
makeSchemaTypeLoader( schemas3 );
Assert.assertTrue( false );
}
catch ( XmlException e )
{
}
}
public void testValidate1 ( )
throws Exception
{
String ericSchema =
"<xs:schema\n" +
" xmlns:xs='http://www.w3.org/2001/XMLSchema'\n" +
" xmlns:nw='http://openuri.org/ericschema'\n" +
" targetNamespace='http://openuri.org/ericschema'\n" +
" elementFormDefault='qualified'>\n" +
"\n" +
" <xs:complexType name='foo'>\n" +
" </xs:complexType>\n" +
"\n" +
" <xs:element name='foo' type='nw:foo'>\n" +
" </xs:element>\n" +
"\n" +
" <xs:element name='eric'>\n" +
" <xs:complexType>\n" +
" <xs:sequence>\n" +
" <xs:element name='a' maxOccurs='unbounded'/>\n" +
" <xs:element name='b' />\n" +
" <xs:any namespace='yaya' minOccurs='0' maxOccurs='1' processContents='lax'/>\n" +
" <xs:element name='c' />\n" +
" <xs:any minOccurs='0' maxOccurs='unbounded' processContents='strict'/>\n" +
" </xs:sequence>\n" +
" <xs:attribute name='x' use='optional'/>\n" +
" <xs:attribute name='y' use='required'/>\n" +
" <xs:attribute name='z' use='prohibited'/>\n" +
" </xs:complexType>\n" +
" </xs:element>\n" +
"" +
"</xs:schema>\n";
String eric2Schema =
"<xs:schema\n" +
" xmlns:xs='http://www.w3.org/2001/XMLSchema'\n" +
" xmlns:nw='http://openuri.org/ericschema2'\n" +
" xmlns:eric='http://openuri.org/ericschema'\n" +
" targetNamespace='http://openuri.org/ericschema2'\n" +
" elementFormDefault='qualified'>\n" +
"\n" +
" <xs:complexType name='eric2'>\n" +
" <xs:complexContent>\n" +
" <xs:extension base='eric:foo'>\n" +
" <xs:sequence>\n" +
" <xs:element name='a' maxOccurs='unbounded'/>\n" +
" </xs:sequence>\n" +
" </xs:extension>\n" +
" </xs:complexContent>\n" +
" </xs:complexType>\n" +
"</xs:schema>\n";
String eric = "<eric y='Y' xmlns='http://openuri.org/ericschema'>";
String eric2 = "<eric xmlns='http://openuri.org/ericschema2'>";
String xsi = "xmlns:eric2='http://openuri.org/ericschema2' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'";
String[] valid = {
eric + "<a/><b/><c/><foo xsi:type='eric2:eric2' " +
xsi + "><a xmlns=\"http://openuri.org/ericschema2\"/></foo></eric>",
eric + "<a/><b/><boo xmlns='yaya'/><c/></eric>",
eric + "<a/><b/><c/></eric>",
eric + "<a x='y'/><b/><c/></eric>",
"<eric y='Y' x='X' xmlns='http://openuri.org/ericschema'>" +
"<a/><b/><c/></eric>"
};
String ericSansY =
"<eric xmlns='http://openuri.org/ericschema'>";
String[] invalid = {
"<foo/>",
"<eric><a/><foo/><c/></eric>",
eric + "text<a/><b/><c/></eric>",
eric + "<a/>text<b/><c/></eric>",
eric + "<a/><b/>text<c/></eric>",
eric + "<a/><b/><c/>text</eric>",
eric + "<a x='y'/><b/><c/>text</eric>",
eric + "<a/><b/><boo xmlns='yaya'/><moo xmlns='yaya'/><c/></eric>",
ericSansY + "<a/><b/><c/></eric>",
"<eric y='' z='' xmlns='http://openuri.org/ericschema'>" +
"<a/><b/><c/></eric>"
};
String[] schemas = { ericSchema, eric2Schema };
doTest(
schemas,
new QName( "http://openuri.org/ericschema", "eric" ),
valid, invalid );
}
public void testValidate2 ( )
throws Exception
{
String bobSchema =
"<xs:schema\n" +
" xmlns:xs='http://www.w3.org/2001/XMLSchema'\n" +
" xmlns:bob='http://openuri.org/bobschema'\n" +
" targetNamespace='http://openuri.org/bobschema'\n" +
" elementFormDefault='qualified'>\n" +
"\n" +
" <xs:complexType name='biff'>\n" +
" <xs:complexContent>\n" +
" <xs:extension base='bob:foo'>\n" +
" <xs:sequence>\n" +
" <xs:element name='a' minOccurs='0' maxOccurs='unbounded'/>\n" +
" </xs:sequence>\n" +
" </xs:extension>\n" +
" </xs:complexContent>\n" +
" </xs:complexType>\n" +
"" +
" <xs:complexType name='foo'>\n" +
" </xs:complexType>\n" +
"" +
" <xs:element name='foo' type='bob:foo'>\n" +
" </xs:element>\n" +
"" +
"</xs:schema>\n";
String xsiType = "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'";
String[] valid = {
"<bob:foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:bob='http://openuri.org/bobschema' " +
"xsi:type='bob:biff'><bob:a/><bob:a/><bob:a/></bob:foo>"
};
String[] invalid = {
"<bob:foo xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:bob='http://openuri.org/bobschema' " +
"xsi:type='bob:biff'><bob:q/></bob:foo>",
"<bob:foo a='b' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:bob='http://openuri.org/bobschema' " +
"xsi:type='bob:biff'><bob:a/><bob:a/><bob:a/></bob:foo>"
};
String[] schemas = { bobSchema };
doTest( schemas, null, valid, invalid );
}
String ns =
"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
"xmlns:xs='http://www.w3.org/2001/XMLSchema'";
public void testValidate3 ( )
throws Exception
{
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
"" +
" <xs:simpleType name='allNNI'>\n" +
" <xs:annotation><xs:documentation>\n" +
" for maxOccurs</xs:documentation></xs:annotation>\n" +
" <xs:union memberTypes='xs:nonNegativeInteger'>\n" +
" <xs:simpleType>\n" +
" <xs:restriction base='xs:NMTOKEN'>\n" +
" <xs:enumeration value='unbounded'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
" </xs:union>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='ericBase64Binary'>\n" +
" <xs:restriction base='xs:base64Binary'>\n" +
" <xs:enumeration value='Eric'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='abcdHexBinary'>\n" +
" <xs:restriction base='xs:hexBinary'>\n" +
" <xs:enumeration value='abcd'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='zeroNumber'>\n" +
" <xs:restriction base='number'>\n" +
" <xs:enumeration value='Zero'/>\n" +
" <xs:enumeration value='0'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='number'>\n" +
" <xs:union>\n" +
" <xs:simpleType>\n" +
" <xs:restriction base='xs:decimal'/>\n" +
" </xs:simpleType>\n" +
" <xs:simpleType>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:whiteSpace value='collapse'/>\n" +
" <xs:enumeration value='Zero'/>\n" +
" <xs:enumeration value='One'/>\n" +
" <xs:enumeration value='Two'/>\n" +
" <xs:enumeration value='Three'/>\n" +
" <xs:enumeration value='Many'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
" </xs:union>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='listOfInt'>\n" +
" <xs:list itemType='xs:int'/>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='listOfPrime'>\n" +
" <xs:list itemType='prime'/>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='ericBrother'>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:whiteSpace value='collapse'/>\n" +
" <xs:enumeration value='Brian'/>\n" +
" <xs:enumeration value='Kevin'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='ericBrothers'>\n" +
" <xs:list itemType='ericBrother'/>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='weekString'>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:whiteSpace value='collapse'/>\n" +
" <xs:enumeration value='Monday'/>\n" +
" <xs:enumeration value='Tuesday'/>\n" +
" <xs:enumeration value='Wednesday'/>\n" +
" <xs:enumeration value='Thursday'/>\n" +
" <xs:enumeration value='Friday'/>\n" +
" <xs:enumeration value='Saturday'/>\n" +
" <xs:enumeration value='Sunday'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='aYear'>\n" +
" <xs:restriction base='xs:duration'>\n" +
" <xs:enumeration value='P1Y'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='ericBDay'>\n" +
" <xs:restriction base='xs:date'>\n" +
" <xs:enumeration value='1965-06-10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='youngerThanEric'>\n" +
" <xs:restriction base='xs:date'>\n" +
" <xs:minExclusive value='1965-06-10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='fiveCharQname'>\n" +
" <xs:restriction base='xs:QName'>\n" +
" <xs:length value='5'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='wackyQname'>\n" +
" <xs:restriction base='xs:QName'>\n" +
" <xs:minLength value='3'/>\n" +
" <xs:maxLength value='10'/>\n" +
" <xs:pattern value='[xs:abcde]*'/>\n" +
" <xs:enumeration value='xs:abc'/>\n" +
" <xs:enumeration value='xs:bcd'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='fiveCharAnyURI'>\n" +
" <xs:restriction base='xs:anyURI'>\n" +
" <xs:length value='5'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='wackyAnyURI'>\n" +
" <xs:restriction base='xs:anyURI'>\n" +
" <xs:minLength value='3'/>\n" +
" <xs:maxLength value='10'/>\n" +
" <xs:enumeration value='foo'/>\n" +
" <xs:enumeration value='bar'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='bit'>\n" +
" <xs:restriction base='xs:boolean'>\n" +
" <xs:pattern value='1|0'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='evenInteger'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:pattern value='[0-9]*[02468]'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='prime'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:pattern value='[0-9]*[13579]'/>\n" +
" <xs:enumeration value='3'/>\n" +
" <xs:enumeration value='5'/>\n" +
" <xs:enumeration value='7'/>\n" +
" <xs:enumeration value='11'/>\n" +
" <xs:enumeration value='13'/>\n" +
" <xs:enumeration value='17'/>\n" +
" <xs:enumeration value='19'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='fourCharString'>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:length value='4'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='threeOrMoreCharString'>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:minLength value='3'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='fiveOrLessCharString'>\n" +
" <xs:restriction base='xs:string'>\n" +
" <xs:maxLength value='5'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='fiveTotalDigits'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:totalDigits value='5'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='threeFractionDigits'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:fractionDigits value='3'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMinExclusive'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:minExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxExclusive'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:maxExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxInclusive'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:maxInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMinInclusive'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:minInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMinExclusiveFloat'>\n" +
" <xs:restriction base='xs:float'>\n" +
" <xs:minExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxExclusiveFloat'>\n" +
" <xs:restriction base='xs:float'>\n" +
" <xs:maxExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxInclusiveFloat'>\n" +
" <xs:restriction base='xs:float'>\n" +
" <xs:maxInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMinInclusiveFloat'>\n" +
" <xs:restriction base='xs:float'>\n" +
" <xs:minInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"\n" +
" <xs:simpleType name='tenMinExclusiveDouble'>\n" +
" <xs:restriction base='xs:double'>\n" +
" <xs:minExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxExclusiveDouble'>\n" +
" <xs:restriction base='xs:double'>\n" +
" <xs:maxExclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMaxInclusiveDouble'>\n" +
" <xs:restriction base='xs:double'>\n" +
" <xs:maxInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"" +
" <xs:simpleType name='tenMinInclusiveDouble'>\n" +
" <xs:restriction base='xs:double'>\n" +
" <xs:minInclusive value='10'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"\n" +
" <xs:element name='any'>\n" +
" </xs:element>\n" +
"" +
" <xs:element name='default_12345' default='12345'>\n" +
" </xs:element>\n" +
"" +
" <xs:element name='default_1234' default='1234'>\n" +
" </xs:element>\n" +
"" +
" <xs:element name='default_eric' default='eric'>\n" +
" </xs:element>\n" +
"" +
"</xs:schema>\n";
String[] valid = {
"<any " + ns + " xsi:type='threeFractionDigits'>.1</any>",
"<any " + ns + " xsi:type='threeFractionDigits'>.12</any>",
"<any " + ns + " xsi:type='threeFractionDigits'>.123</any>",
"<any " + ns + " xsi:type='allNNI'>unbounded</any>",
"<any " + ns + " xsi:type='allNNI'>0</any>",
"<any " + ns + " xsi:type='allNNI'>1</any>",
"<any " + ns + " xsi:type='xs:base64Binary'>CAFEBABE</any>",
"<any " + ns + " xsi:type='abcdHexBinary'>abcd</any>",
"<any " + ns + " xsi:type='xs:base64Binary'>abcdefgh</any>",
"<any " + ns + " xsi:type='ericBase64Binary'>Eric</any>",
"<any " + ns + " xsi:type='zeroNumber'> Zero</any>",
"<any " + ns + " xsi:type='zeroNumber'>Zero</any>",
"<any " + ns + " xsi:type='zeroNumber'>0</any>",
"<any " + ns + " xsi:type='number'>1</any>",
"<any " + ns + " xsi:type='number'> 1 </any>",
"<any " + ns + " xsi:type='number'>Two</any>",
"<any " + ns + " xsi:type='number'> Three </any>",
"<any " + ns + " xsi:type='ericBrothers'></any>",
"<any " + ns + " xsi:type='ericBrothers'>Brian</any>",
"<any " + ns + " xsi:type='ericBrothers'>Kevin</any>",
"<any " + ns + " xsi:type='ericBrothers'>Kevin Brian</any>",
"<any " + ns + " xsi:type='ericBrothers'>Brian Kevin</any>",
"<any " + ns + " xsi:type='listOfInt'> 1 22 333 4444 </any>",
"<any " + ns + " xsi:type='listOfInt'></any>",
"<any " + ns + " xsi:type='listOfInt'>5999</any>",
"<any " + ns + " xsi:type='aYear'>P1Y</any>",
"<any " + ns + " xsi:type='fiveCharAnyURI'>abcde</any>",
"<any " + ns + " xsi:type='xs:anyURI'>foo</any>",
"<any " + ns + " xsi:type='wackyAnyURI'>foo</any>",
"<any " + ns + " xsi:type='youngerThanEric'>1965-06-11</any>",
"<any " + ns + " xsi:type='ericBDay'>1965-06-10</any>",
"<any " + ns + " xsi:type='xs:dateTime'>1999-05-31T13:20:00-05:00</any>",
"<any " + ns + " xsi:type='xs:time'>00:00:00</any>",
"<any " + ns + " xsi:type='xs:time'>13:20:00-05:00</any>",
"<any " + ns + " xsi:type='wackyQname'>xs:abc</any>",
"<any " + ns + " xsi:type='fiveCharQname'>abcde</any>",
"<any " + ns + " xsi:type='fiveCharQname'>xs:ab</any>",
"<any " + ns + " xsi:type='prime'>3</any>",
"<any " + ns + " xsi:type='prime'>11</any>",
"<any " + ns + " xsi:type='xs:integer'>+45</any>",
"<any " + ns + " xsi:type='xs:integer'>1</any>",
"<any " + ns + " xsi:type='xs:integer'>0</any>",
"<any " + ns + " xsi:type='xs:integer'>-1</any>",
"<any " + ns + " xsi:type='xs:integer'>-1</any>",
"<any " + ns + " xsi:type='xs:integer'>489743579837589743434</any>",
"<any " + ns + " xsi:type='xs:boolean'>1</any>",
"<default_1234 " + ns + " xsi:type='evenInteger'></default_1234>",
"<any " + ns + " xsi:type='evenInteger'>12</any>",
"<any " + ns + " xsi:type='bit'>1</any>",
"<any " + ns + " xsi:type='bit'>0</any>",
"<any " + ns + " xsi:type='xs:boolean'>false</any>",
"<any " + ns + " xsi:type='evenInteger'>0</any>",
"<any " + ns + " xsi:type='weekString'>Monday</any>",
"<any " + ns + " xsi:type='weekString'>Sunday</any>",
"<any " + ns + " xsi:type='weekString'> Thursday </any>",
"<any " + ns + " xsi:type='tenMinExclusive'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusive'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusive'>10</any>",
"<any " + ns + " xsi:type='tenMinInclusive'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxInclusive'>10</any>",
"<any " + ns + " xsi:type='tenMaxInclusive'>9.9</any>",
"<any " + ns + " xsi:type='tenMinExclusiveFloat'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveFloat'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusiveFloat'>10</any>",
"<any " + ns + " xsi:type='tenMinInclusiveFloat'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveFloat'>10</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveFloat'>9.9</any>",
"<any " + ns + " xsi:type='tenMinExclusiveDouble'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveDouble'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusiveDouble'>10</any>",
"<any " + ns + " xsi:type='tenMinInclusiveDouble'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveDouble'>10</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveDouble'>9.9</any>",
"<any " + ns + " xsi:type='fourCharString'>eric</any>",
"<any " + ns + " xsi:type='threeOrMoreCharString'>12345</any>",
"<any " + ns + " xsi:type='fiveOrLessCharString'>1234</any>",
"<any " + ns + " xsi:type='fiveTotalDigits'>12345</any>",
"<any " + ns + " xsi:type='fiveTotalDigits'>1234</any>",
"<default_1234 " + ns + " xsi:type='evenInteger'>\n\n</default_1234>"
};
String[] invalid = {
"<any " + ns + " xsi:type='allNNI'>foo</any>",
"<any " + ns + " xsi:type='xs:hexBinary'>P</any>",
"<any " + ns + " xsi:type='xs:hexBinary'>CAFEBABP</any>",
"<any " + ns + " xsi:type='abcdHexBinary'>abce</any>",
"<any " + ns + " xsi:type='xs:base64Binary'>abcde</any>",
"<any " + ns + " xsi:type='ericBase64Binary'>Erik</any>",
"<any " + ns + " xsi:type='zeroNumber'>One</any>",
"<any " + ns + " xsi:type='zeroNumber'>Twenty</any>",
"<any " + ns + " xsi:type='number'>Seven</any>",
"<any " + ns + " xsi:type='number'>Bob</any>",
"<any " + ns + " xsi:type='number'></any>",
"<any " + ns + " xsi:type='ericBrothers'>1</any>",
"<any " + ns + " xsi:type='ericBrothers'>Bob</any>",
"<any " + ns + " xsi:type='ericBrothers'>Ralph Frank</any>",
"<any " + ns + " xsi:type='listOfInt'> 1 22 333 Eric </any>",
"<any " + ns + " xsi:type='listOfInt'>Eric</any>",
"<any " + ns + " xsi:type='listOfInt'>-</any>",
"<any " + ns + " xsi:type='aYear'>P2Y</any>",
"<any " + ns + " xsi:type='youngerThanEric'>1965-06-10</any>",
"<any " + ns + " xsi:type='ericBDay'>1985-06-10</any>",
"<any " + ns + " xsi:type='xs:dateTime'>xx1999-05-31T13:20:00-05:00</any>",
"<any " + ns + " xsi:type='xs:dateTime'>eric</any>",
"<any " + ns + " xsi:type='xs:time'>99:99:00</any>",
"<any " + ns + " xsi:type='xs:time'>13:20:00-99:00</any>",
"<any " + ns + " xsi:type='wackyAnyURI'>moo</any>",
"<any " + ns + " xsi:type='fiveCharAnyURI'>ab</any>",
"<any " + ns + " xsi:type='wackyQname'>xs:abcdefghijk</any>",
"<any " + ns + " xsi:type='wackyQname'>xs:pqr</any>",
"<any " + ns + " xsi:type='xs:QName'>foo:bar</any>",
"<any " + ns + " xsi:type='fiveCharQname'>xs:abc</any>",
"<any " + ns + " xsi:type='prime'>12</any>",
"<any " + ns + " xsi:type='prime'>6</any>",
"<any " + ns + " xsi:type='xs:integer'>foo</any>",
"<any " + ns + " xsi:type='xs:integer'>.1</any>",
"<any " + ns + " xsi:type='evenInteger'>1</any>",
"<any " + ns + " xsi:type='bit'>true</any>",
"<any " + ns + " xsi:type='bit'>false</any>",
"<any " + ns + " xsi:type='bit'>nibble</any>",
"<any " + ns + " xsi:type='bit'>2</any>",
"<any " + ns + " xsi:type='xs:boolean'>blurf</any>",
"<any " + ns + " xsi:type='xs:boolean'></any>",
"<any " + ns + " xsi:type='evenInteger'></any>",
"<any " + ns + " xsi:type='weekString'>Monday Sucks</any>",
"<any " + ns + " xsi:type='tenMaxExclusive'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusive'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusive'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusive'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusive'>9.9</any>",
"<any " + ns + " xsi:type='tenMaxInclusive'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveFloat'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveFloat'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusiveFloat'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusiveFloat'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusiveFloat'>9.9</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveFloat'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveDouble'>10.1</any>",
"<any " + ns + " xsi:type='tenMaxExclusiveDouble'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusiveDouble'>10</any>",
"<any " + ns + " xsi:type='tenMinExclusiveDouble'>9.9</any>",
"<any " + ns + " xsi:type='tenMinInclusiveDouble'>9.9</any>",
"<any " + ns + " xsi:type='tenMaxInclusiveDouble'>10.1</any>",
"<any " + ns + " xsi:type='fiveOrLessCharString'> 1234 </any>",
"<any " + ns + " xsi:type='fiveTotalDigits'>123456</any>",
"<any " + ns + " xsi:type='fourCharString'>vasilik</any>",
"<any " + ns + " xsi:type='threeOrMoreCharString'>1</any>",
"<any " + ns + " xsi:type='fiveOrLessCharString'>1234567</any>",
"<any " + ns + " xsi:type='threeFractionDigits'>.1234</any>",
"<any " + ns + " xsi:type='fourCharString'> eric </any>",
"<default_12345 " + ns + " xsi:type='evenInteger'></default_12345>",
"<default_12345 " + ns + " xsi:type='evenInteger'>\n\n</default_12345>"
};
String[] schemas = { schema };
doTest( schemas, null, valid, invalid );
}
public void testValidate4 ( )
throws Exception
{
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
"\n" +
" <xs:element name='any'>\n" +
" </xs:element>\n" +
"\n" +
" <xs:simpleType name='kindaPrime'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:pattern value='[0-9]*[13579]'/>\n" +
" <xs:enumeration value='3'/>\n" +
" <xs:enumeration value='5'/>\n" +
" <xs:enumeration value='7'/>\n" +
" <xs:enumeration value='11'/>\n" +
" <xs:enumeration value='13'/>\n" +
" <xs:enumeration value='17'/>\n" +
" <xs:enumeration value='19'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"\n" +
"</xs:schema>\n" +
"";
String[] schemas = { schema };
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
XmlObject x =
stl.parse(
"<any " + ns + " xsi:type='kindaPrime'>100</any>",
null, null );
// Make sure the unvalidated stream is OK
XMLInputStream xis = x.newXMLInputStream();
while ( xis.hasNext() )
xis.next();
// Make sure the validated stream fails
boolean blewChunks = false;
xis =
stl.newValidatingXMLInputStream(
x.newXMLInputStream(), null, null );
try
{
while ( xis.hasNext() )
xis.next();
}
catch ( XMLStreamValidationException e )
{
blewChunks = true;
}
Assert.assertTrue( blewChunks );
}
public void testValidate5 ( )
throws Exception
{
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
"\n" +
" <xs:element name='hee'>\n" +
" <xs:complexType>\n" +
" <xs:sequence>\n" +
" <xs:element name='haw' type='xs:int'/>\n" +
" </xs:sequence>\n" +
" <xs:attribute name='yee' type='xs:int'/>\n" +
" </xs:complexType>\n" +
" </xs:element>\n" +
"\n" +
" <xs:simpleType name='kindaPrime'>\n" +
" <xs:restriction base='xs:decimal'>\n" +
" <xs:pattern value='[0-9]*[13579]'/>\n" +
" <xs:enumeration value='3'/>\n" +
" <xs:enumeration value='5'/>\n" +
" <xs:enumeration value='7'/>\n" +
" <xs:enumeration value='11'/>\n" +
" <xs:enumeration value='13'/>\n" +
" <xs:enumeration value='17'/>\n" +
" <xs:enumeration value='19'/>\n" +
" </xs:restriction>\n" +
" </xs:simpleType>\n" +
"\n" +
"</xs:schema>\n" +
"";
String[] schemas = { schema };
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
XmlObject x =
stl.parse(
"<hee yee='3'><haw>66</haw></hee>",
null, null );
XmlCursor c = x.newCursor();
for ( ; ; )
{
XmlObject obj = c.getObject();
if (obj != null)
obj.validate();
if (c.toNextToken().isNone())
break;
}
// invalid
x =
stl.parse(
"<hee yee='five'><haw>66</haw></hee>",
null, null );
Assert.assertTrue( ! x.validate() );
c = x.newCursor();
c.toNextToken();
c.toNextToken();
Assert.assertTrue( ! c.getObject().validate() );
// No schema
x = XmlObject.Factory.parse( "<foo x='y'>asas<bar>asas</bar></foo>" );
c = x.newCursor();
for ( ; ; )
{
XmlObject obj = c.getObject();
if (obj != null)
obj.validate();
if (c.toNextToken().isNone())
break;
}
}
public void testValidate6 ( )
throws Exception
{
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
" <xs:element name='hee'>\n" +
" </xs:element>\n" +
"</xs:schema>\n" +
"";
String[] schemas = { schema, schema };
// Should get a schema compile error
try
{
makeSchemaTypeLoader( schemas );
Assert.assertTrue( false );
}
catch ( XmlException e )
{
}
}
public void testValidate7 ( )
throws Exception
{
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>" +
"" +
" <xs:element name='base' type='base'/>" +
"" +
" <xs:complexType name='base'>" +
" <xs:sequence>" +
" <xs:element name='foo'/>" +
" </xs:sequence>" +
" </xs:complexType>" +
"" +
" <xs:complexType name='derived'>" +
" <xs:complexContent>" +
" <xs:extension base='base'>" +
" <xs:sequence>" +
" <xs:element name='bar'/>" +
" </xs:sequence>" +
" </xs:extension>" +
" </xs:complexContent>" +
" </xs:complexType>" +
"" +
"</xs:schema>" +
"";
String[] schemas = { schema };
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
XmlObject x =
stl.parse(
"<base><foo/></base>", null, null );
Assert.assertTrue( x.validate() );
XmlCursor c = x.newCursor();
c.toFirstChild();
XmlObject base = c.getObject();
c.toEndToken();
c.insertElement( "bar" );
Assert.assertTrue( !x.validate() );
c.toPrevSibling();
c.removeXml();
Assert.assertTrue( x.validate() );
base.changeType( stl.findType( new QName( "derived" ) ) );
c.insertElement( "bar" );
Assert.assertTrue( x.validate() );
}
// Tests abstract & block attributes on ComplexType
public void testValidate8() throws Exception
{
String[] schemas = {
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>" +
"" +
" <xs:element name='abstract' type='abstract'/>" +
" <xs:element name='base' type='base'/>" +
"" +
" <xs:complexType name='abstract' abstract='true'/>" +
"" +
" <xs:complexType name='concrete'>" +
" <xs:complexContent>" +
" <xs:extension base='abstract'/>" +
" </xs:complexContent>" +
" </xs:complexType>" +
"" +
" <xs:complexType name='base' block='extension'/>" +
"" +
" <xs:complexType name='ext'>" +
" <xs:complexContent>" +
" <xs:extension base='base'/>" +
" </xs:complexContent>" +
" </xs:complexType>" +
"" +
" <xs:complexType name='rest'>" +
" <xs:complexContent>" +
" <xs:restriction base='base'/>" +
" </xs:complexContent>" +
" </xs:complexType>" +
"" +
"</xs:schema>" +
"",
};
String xsiType = " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' ";
String[] valid = {
"<abstract" + xsiType + "xsi:type='concrete'/>",
"<base/>",
"<base" + xsiType + "xsi:type='rest'/>",
};
String[] invalid = {
"<abstract/>",
"<base" + xsiType + "xsi:type='ext'/>",
};
doTest(schemas, null, valid, invalid);
}
public void testValidate9() throws Exception
{
String[] schemas = {
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>" +
" <xs:element name='order' type='OrderType'>" +
" <xs:keyref name='prodNumKeyRef' refer='prodNumKey'>" +
" <xs:selector xpath='items/*'/>" +
" <xs:field xpath='@number'/>" +
" </xs:keyref>" +
" <xs:key name='prodNumKey'>" +
" <xs:selector xpath='.//product'/>" +
" <xs:field xpath='number'/>" +
" </xs:key>" +
" </xs:element>" +
" <xs:complexType name='OrderType'>" +
" <xs:sequence>" +
" <xs:element name='items'>" +
" <xs:complexType>" +
" <xs:sequence>" +
" <xs:element name='item' type='ItemType' minOccurs='0' maxOccurs='unbounded'/>" +
" </xs:sequence>" +
" </xs:complexType>" +
" </xs:element>" +
" <xs:element name='products'>" +
" <xs:complexType>" +
" <xs:sequence>" +
" <xs:element name='product' type='ProductType' maxOccurs='unbounded' minOccurs='0'/>" +
" </xs:sequence>" +
" </xs:complexType>" +
" </xs:element>" +
" </xs:sequence>" +
" <xs:attribute name='number' type='xs:string'/>" +
" </xs:complexType>" +
" <xs:complexType name='ItemType'>" +
" <xs:sequence>" +
" <xs:element name='quantity' type='xs:int'/>" +
" </xs:sequence>" +
" <xs:attribute name='number' type='xs:int'/>" +
" </xs:complexType>" +
" <xs:complexType name='ProductType'>" +
" <xs:sequence>" +
" <xs:element name='number' type='xs:int' minOccurs='0'/>" +
" <xs:element name='name' type='xs:string'/>" +
" <xs:element name='price'>" +
" <xs:complexType>" +
" <xs:simpleContent>" +
" <xs:extension base='xs:decimal'>" +
" <xs:attribute name='currency' type='xs:string'/>" +
" </xs:extension>" +
" </xs:simpleContent>" +
" </xs:complexType>" +
" </xs:element>" +
" </xs:sequence>" +
" </xs:complexType>" +
"</xs:schema> ",
"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
" <xsd:element name='root' type='RootType'>" +
" <xsd:key name='FooId'>" +
" <xsd:selector xpath='.//string|.//token|.//int'/>" +
" <xsd:field xpath='@id'/>" +
" </xsd:key>" +
" </xsd:element>" +
" <xsd:group name='group'>" +
" <xsd:choice>" +
" <xsd:element ref='string'/>" +
" <xsd:element ref='token'/>" +
" <xsd:element ref='int'/>" +
" </xsd:choice>" +
" </xsd:group>" +
" <xsd:complexType name='RootType'>" +
" <xsd:group ref='group' minOccurs='0' maxOccurs='unbounded'/>" +
" </xsd:complexType>" +
" <xsd:element name='string'>" +
" <xsd:complexType>" +
" <xsd:group ref='group' minOccurs='0' maxOccurs='unbounded'/>" +
" <xsd:attribute name='id' type='xsd:string'/>" +
" </xsd:complexType>" +
" </xsd:element>" +
" <xsd:element name='int'>" +
" <xsd:complexType>" +
" <xsd:group ref='group' minOccurs='0' maxOccurs='unbounded'/>" +
" <xsd:attribute name='id' type='xsd:int'/>" +
" </xsd:complexType>" +
" </xsd:element>" +
" <xsd:element name='token'>" +
" <xsd:complexType>" +
" <xsd:group ref='group' minOccurs='0' maxOccurs='unbounded'/>" +
" <xsd:attribute name='id' type='xsd:token'/>" +
" </xsd:complexType>" +
" </xsd:element>" +
"</xsd:schema>",
"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' " +
" targetNamespace='http://www.tim-hanson.com/' xmlns:th='http://www.tim-hanson.com/' " +
" attributeFormDefault='qualified' elementFormDefault='qualified'>" +
" <xsd:element name='root'>" +
" <xsd:complexType>" +
" <xsd:sequence>" +
" <xsd:element name='foo' maxOccurs='unbounded'>" +
" <xsd:complexType>" +
" <xsd:attribute name='id' type='xsd:int'/>" +
" </xsd:complexType>" +
" </xsd:element>" +
" </xsd:sequence>" +
" </xsd:complexType>" +
" <xsd:key name='id'>" +
" <xsd:selector xpath='./th:foo'/>" +
" <xsd:field xpath='@th:id'/>" +
" </xsd:key>" +
" </xsd:element>" +
"</xsd:schema>",
"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' >" +
" <xsd:element name='idtest'>" +
" <xsd:complexType>" +
" <xsd:sequence maxOccurs='unbounded'>" +
" <xsd:choice>" +
" <xsd:element name='id' maxOccurs='unbounded' type='xsd:ID'/>" +
" <xsd:element name='idref' maxOccurs='unbounded' type='xsd:IDREF'/>" +
" <xsd:element name='idrefs' maxOccurs='unbounded' type='xsd:IDREFS'/>" +
" </xsd:choice>" +
" </xsd:sequence>" +
" </xsd:complexType>" +
" </xsd:element>" +
"</xsd:schema>",
};
String[] valid = {
"<order>" +
" <items>" +
" <item number='124 '>" +
" <quantity>1</quantity>" +
" </item>" +
" <item number='563'>" +
" <quantity>1</quantity>" +
" </item>" +
" </items>" +
" <products>" +
" <product>" +
" <number> 124</number>" +
" <name>Shirt</name>" +
" <price currency='USD'>29.99</price>" +
" </product>" +
" <product>" +
" <number>563</number>" +
" <name>Hat</name>" +
" <price currency='USD'>69.99</price>" +
" </product>" +
" <product>" +
" <number>443</number>" +
" <name>Umbrella</name>" +
" <price currency='USD'>49.99</price>" +
" </product>" +
" </products>" +
"</order>",
"<root>" +
" <string id='foo1'>" +
" <string id='foo2'>" +
" <string id='foo3'>" +
" <string id='foo6'>" +
" <string id='foo7'>" +
" <string id='foo8'/>" +
" </string>" +
" </string>" +
" </string>" +
" <string id='foo4'/>" +
" </string>" +
" <string id='foo9'/>" +
" </string>" +
"</root>",
"<root>" +
" <int id='1'/>" +
" <string id='1'/>" +
"</root>",
"<xyz:root xmlns:xyz='http://www.tim-hanson.com/'>" +
" <xyz:foo xyz:id='1'/>" +
" <xyz:foo xyz:id='2'/>" +
" <xyz:foo xyz:id='3'/>" +
"</xyz:root>",
"<idtest>" +
" <idref>xyz</idref>" +
" <idrefs>abc def</idrefs>" +
" <id>abc</id>" +
" <id>def</id>" +
" <id>xyz</id>" +
" <idref>abc</idref>" +
" <idrefs>xyz abc</idrefs>" +
"</idtest>",
};
String[] invalid = {
"<order>" +
" <items>" +
" <item number='125 '>" +
" <quantity>1</quantity>" +
" </item>" +
" <item number='563'>" +
" <quantity>1</quantity>" +
" </item>" +
" </items>" +
" <products>" +
" <product>" +
" <number> 124</number>" +
" <name>Shirt</name>" +
" <price currency='USD'>29.99</price>" +
" </product>" +
" <product>" +
" <number>563</number>" +
" <name>Hat</name>" +
" <price currency='USD'>69.99</price>" +
" </product>" +
" <product>" +
" <number>443</number>" +
" <name>Umbrella</name>" +
" <price currency='USD'>49.99</price>" +
" </product>" +
" </products>" +
"</order>",
"<root>" +
" <token token=' blah blah'/>" +
" <string id='blah blah'/>" +
"</root>",
"<root>" +
" <string id='foo1'>" +
" <string id='foo2'>" +
" <string id='foo3'>" +
" <string id='foo6'>" +
" <string id='foo7'>" +
" <string id='foo3'/>" +
" </string>" +
" </string>" +
" </string>" +
" </string>" +
" </string>" +
"</root>",
"<xyz:root xmlns:xyz='http://www.tim-hanson.com/'>" +
" <xyz:foo xyz:id='1'/>" +
" <xyz:foo xyz:id='2'/>" +
" <xyz:foo xyz:id='2'/>" +
"</xyz:root>",
};
String[] invalidOnDocOnly = new String[]
{
"<idtest>" +
" <idref>foo</idref>" +
" <id>abc</id>" +
" <id>def</id>" +
" <id>xyz</id>" +
"</idtest>",
"<idtest>" +
" <idrefs>abc foo</idrefs>" +
" <id>abc</id>" +
" <id>def</id>" +
" <id>xyz</id>" +
"</idtest>",
};
doTest(schemas, null, valid, invalid, true);
doTest(schemas, null, valid, invalid, false);
// IDRefs are validated only if starting at the very root of the world
doTest(schemas, null, new String[0], invalidOnDocOnly, true);
doTest(schemas, null, invalidOnDocOnly, new String[0], false);
}
// Test validation of setting with the ValidateOnSet option
public void testValidate10() throws Exception {
String schema =
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n" +
" <xs:simpleType name='dec-restriction'>" +
" <xs:restriction base='xs:decimal'>" +
" <xs:maxExclusive value='100'/>" +
" </xs:restriction>" +
" </xs:simpleType>" +
"</xs:schema>" +
"";
String[] schemas = { schema };
SchemaTypeLoader stl = makeSchemaTypeLoader( schemas );
XmlOptions validate = new XmlOptions().setValidateOnSet();
XmlOptions noValidate = new XmlOptions();
SchemaType st = stl.findType(new QName("", "dec-restriction"));
XmlDecimal dec = (XmlDecimal)stl.newInstance(st, validate);
try {
dec.set("200");
fail("Expected XmlValueOutOfRangeException");
}
catch (XmlValueOutOfRangeException e) {}
dec = (XmlDecimal)stl.newInstance(st, noValidate);
try {
dec.set("200");
}
catch (XmlValueOutOfRangeException e) {
fail("Should not throw exception");
}
}
// Bugzilla bug #26105: validate derived type from base type enumeration
public void testValidate11() throws Exception {
String schemas[] = {
"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>\n" +
"<xsd:element name='enumDef' type='enumDefType'/>\n" +
"<xsd:complexType name='enumDefType'>\n" +
" <xsd:simpleContent>\n" +
" <xsd:extension base='enumType'/>\n" +
" </xsd:simpleContent>\n" +
"</xsd:complexType>\n" +
"<xsd:simpleType name='enumType'>\n" +
" <xsd:restriction base='xsd:token'>\n" +
" <xsd:enumeration value='enum1'/>\n" +
" </xsd:restriction>\n" +
"</xsd:simpleType>\n" +
"</xsd:schema>\n",
};
String[] valid = {
"<enumDef>enum1</enumDef>",
};
String[] invalid = {
"<enumDef>enum2/enumDef>",
};
doTest(schemas, null, valid, invalid);
}
}