To get your first example to run I had to remove a trailing space in the namespace URI
 
sacont.declareNamespace( "sh", "uri://www.test.com " );
I don't think that's particularly relevant to your questions, though it's an interesting debating topic.
 
When I remove the config.addSchemaSource() call, I get the error
 
No schema has been imported for namespace 'uri://www.test.com'
 
This is because your XPath expression contains a reference to a type defined in this schema, sh:nameType. The source document will still be validated using the schema identified in its xsi:schemaLocation attribute, but the source document isn't involved when the XPath expression is compiled. In the jargon of the spec, any type mentioned in an XPath expression needs to be defined in the static context of the expression. In the case of XPath (as distinct from XSLT and XQuery) there's no "import schema" syntax to achieve that, it's up to the API design to work out how the static context is established (and there's no standard API for XPath 2.0 yet). StandaloneContext is (one) Saxon implementation of a static context for XPath expressions, and it makes every schema known to the Configuration part of the static context for the expression.
 
To demonstrate this further, change your schema so that nameType is a restriction of xs:NMTOKEN, and change your XPath expression to //element(*, xs:NMTOKEN). The element is now selected. That's because xs:NMTOKEN, unlike sh:nameType, is a built-in type and you don't need to do anything special to make it available in the static context.
 
To make this work, I changed the source XML to use the relative path "test.xsd" to refer to the schema, and I changed the source program to say
 
new StreamSource( new File( "c:/MyJava/users/costello/test.xml" ) )
 
rather than
 
new StreamSource( new FileInputStream( "c:/MyJava/users/costello/test.xml" ) )
 
The trouble about supplying a FileInputStream is that the original location of the source document isn't known, and the system then can't resolve a relative URI referring to the schema. However, this is an aside to your main question.
 
As a further demonstration, change the Configuration to set Validation.SKIP, and the element is no longer selected, because it is no longer an instance of xs:NMTOKEN.
 
In summary, there are two separate things going on: you have to tell the XPath processor at compile time where to find any schema types referenced in the expression, and you have to tell the document loader where to find any schema definitions used for validating the source. Loading the schema into the Configuration kills both these birds with one stone.
 
Finally, XOM. At present, only the TinyTree supports schema-aware processing, that is, this is the only implementation of the data model that can currently hold the type annotations that result from schema validation. I'm sure other implementations will come in time, but that's the situation today.
 
I hope this helps!
 
Michael Kay
http://www.saxonica.com/


From: saxon-help-admin@lists.sourceforge.net [mailto:saxon-help-admin@lists.sourceforge.net] On Behalf Of Cass Costello
Sent: 05 November 2005 18:43
To: saxon-help@lists.sourceforge.net
Subject: [saxon] A couple beginner's issues with schema-aware processing

Hello, all. 

First, thanks to everyone who contributes to this list, and congratulations, Mike, on the CR milestones and 8.6. You probably need a vacation. :)

I grabbed the eval version of Saxon-SA and have been attempting to write some code to wrap my head around the mechanics of schema-aware processing.  Specfically, I'm interested in type-based xpath expressions, and have constructed a couple tests that should a) parse an xml stream into a supported object model ( I'm playing with tinytrees and XOM ), and b) execute an xpath expression that should return an element of a specific schema type.

I've bumbed into 2 issues.  First, though I've specified a schemaLocation in my test xml, the schema is not auto-loaded during the parsing process.  I see "unknown type" errors unless I manually load the associated schema via a SchemaAwareConfiguration.  Once loaded, however, everything works as expected.

Test case...

    public void testSaxonXpathStuff() throws Exception {
       
        SchemaAwareConfiguration config = new SchemaAwareConfiguration();
       
        //why is this necessary given xsi:schemaLocation in instance xml?
        File testSchema = new File( "test/resources/test.xsd" );
        config.addSchemaSource( new StreamSource( testSchema ) );
       
        config.setSchemaValidationMode( Validation. STRICT );    
       
        XPathFactory xpf = XPathFactory.newInstance( NamespaceConstant.OBJECT_MODEL_SAXON );
        XPath xpathObj = xpf.newXPath();
        XPathEvaluator xpe = ( XPathEvaluator) xpathObj;
        StandaloneContext saCtx = new StandaloneContext( config );
       
        saCtx.declareNamespace( "sh", "uri://www.test.com " );
        xpe.setStaticContext( saCtx );
       
        XPathExpression xpathObjExp = xpathObj.compile( (String) "//element( *, sh:nameType )[1]" );   
       
        NodeInfo node = TinyBuilder.build( new StreamSource( new FileInputStream( "test/resources/test.xml" ) ),
                null,
                config );
       
        String result = (String) xpathObjExp.evaluate( node, XPathConstants.STRING );  
       
        assertEquals( "Cass", result );
    }

Second, moving the code from using tinytress to XOM objects results in the expression returning nothing at all.  I assume that there's some step I'm missing around parsing, but I don't know where to go next.  Any help or insight would be apprecated.

    public void testXomXpathStuff() throws Exception {
       
        XMLReader xerces = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
        xerces.setFeature(" http://apache.org/xml/features/validation/schema ", true);
       
        Builder parser = new Builder(xerces, true);
        Document doc = parser.build("test/resources/test.xml" );
       
        SchemaAwareConfiguration config = new SchemaAwareConfiguration();

                  //why is this necessary given xsi:schemaLocation in instance xml?
        File testSchema = new File( "test/resources/test.xsd" );
        config.addSchemaSource( new StreamSource( testSchema ) );

        config.setSchemaValidationMode( Validation.STRICT );    
       
        XPathFactory xpf = XPathFactory.newInstance( NamespaceConstant.OBJECT_MODEL_XOM );
        XPath xpathObj = xpf.newXPath();
        XPathEvaluator xpe = ( XPathEvaluator) xpathObj;
        StandaloneContext sacont = new StandaloneContext( config );
       
        sacont.declareNamespace( "sh", "uri://www.test.com " );

        xpe.setStaticContext( sacont );
        XPathExpression xpathObjExp = xpathObj.compile( (String) "//element( *, sh:nameType )[1]" );   
       
        String result = (String) xpathObjExp.evaluate( doc, XPathConstants.STRING );
       
        //fails - result is ""
        assertEquals( "Cass", result );
    }

I've attached the xml and xsd. 

Thanks for your time,
-Cass