OK, I think I get it: the person who wrote this path expression knew that it was reading books.xml and that books.xml uses a particular schema that contains an element declaration for ITEM; but the person who wrote the Java application that runs the path expression doesn't know what document it reads and doesn't know what schema that uses. Is that a fair summary?

The problem is that the path expression has to be compiled before it can be executed, and the schema is needed at compile time, while books.xml is only read at run-time.

The situation is very much the same as if the path expression contained a reference to a parameter $size. This would fail unless the Java application binds a value to this variable. The author of the path expression (in both cases) has written code with a dependency on the external environment, and that dependency needs to be satisfied in order for the path expression to be executable.

The only suggestion I could make would be to use XQuery, where you could add an "import schema" to make the dependency explicit.

On 27/08/2010 10:03 PM, Malix Ren wrote:
Thanks Michael.
The scenario is, the input document is uncertain.
E.g., the whole xpath expression comes from another xml file. 
<foo:bar test="doc('books.xml')//schema-element(ITEM)" />

Is there a way to catch the 'books.xml'? 
Then we can either do a validation through saxon, or check the xsi:schemaLocation attribute.

Thanks and best regards
Alix

On Fri, Aug 27, 2010 at 1:39 PM, Michael Kay <mike@saxonica.com> wrote:

The rule is that if certain constructs are used in your query/XPath source, including schema-element(E), then the construct they refer to (element declaration E in this case) must be in a schema that's in the static context at the time you compile. XQuery and XSLT specify how schemas get imported into the static context (xsl:import-schema in the case of XSLT, "import schema" in the prolog in the case of XQuery), but XPath leaves it up to the API designer, and for this particular API (a hybrid of JAXP plus Saxon extensions) that's done using the importSchema() method.

However, you don't actually have to use importSchema(): in this API, all schema components known to the Configuration at the time the XPath expression is compiled are considered to be part of its static context. If you parsed and validated the input document before compiling the query, the schema it uses (for example the schema built from its xsi:schemaLocation attribute) would be present in the Configuration and therefore in the static context of the XPath expression.

Michael Kay
Saxonica





On 27/08/2010 7:58 PM, Alix Ren wrote:
Hi Michael,
For saxon-ee, when schema feature is enabled, it seems schema has to be imported explicitly.
E.g., to evaluate xpath expression "doc($filename)//schema-element(ITEM)",
is there a way to supply schema dynamically based on xsi:schemaLocation within the input file?

The following snippet is a modification from saxon-resources9-2-0-2/samples/java/XPathExampleSA.java.
It will raise an error "No schema has been imported for namespace ''", because schema was not imported.

public void go(String filename, String schema) throws Exception {
   
            // Load an XPath factory. This should load the Saxon schema-aware factory if everything has
            // been configured correctly.
   
            EnterpriseXPathFactory xpf = new EnterpriseXPathFactory();
            xpf.getConfiguration().setTiming(true);
            xpf.getConfiguration().displayLicenseMessage();
            xpf.setFeature(net.sf.saxon.FeatureKeys.SCHEMA_VALIDATION, true);
            XPath xpe = xpf.newXPath();
            System.err.println("Loaded XPath Provider " + xpe.getClass().getName() +
                    " using factory " + xpf.getClass().getName());
   
            // Check that we really have loaded a schema-aware XPath processor
   
            if (!xpf.getFeature("http://saxon.sf.net/feature/schema-validation")) {
                System.err.println("Error: this XPath provider is not schema-aware");
                System.exit(2);
            }
   
            // Declare a variable resolver to return the value of variables used in XPath expressions
            xpe.setXPathVariableResolver(this);
   
            // Declare a function resolver to handle the function call in the XPath expression
            xpe.setXPathFunctionResolver(this);
   
            // Import the schema for types references in the XPath expression
            // ((XPathEvaluator)xpe).importSchema(new StreamSource(schema));


            // Compile the XPath expressions used by the application
            xpe.setNamespaceContext(this);

            XPathExpression findBooks = null;
            try {
                findBooks = xpe.compile("doc('"+filename+"')//schema-element(ITEM)" +
                                        "[PUB-DATE gt (current-date() - xs:yearMonthDuration($age))]" +
                                        "[min((f:toCentimetres(data(DIMENSIONS) treat as dimensionType*, " +
                                               "data(DIMENSIONS/@UNIT)))) gt $thickness]" +
                                        "/TITLE");
            } catch (XPathExpressionException e) {
                System.err.println("Error in XPath Expression");
                System.err.println(e.getCause().getMessage());
                System.exit(2);
            }
   
            // Find the titles matching the specified criteria
            DOMNodeList matchedLines = (DOMNodeList) findBooks.evaluate(null, XPathConstants.NODESET);
   
            // Process these lines
            boolean found = false;
            if (matchedLines != null) {
                for (int i=0; i<matchedLines.getLength(); i++) {
   
                    // Note that we have found at least one line
                    found = true;
   
                    // Get the next matching title
                    ElementOverNodeInfo book = (ElementOverNodeInfo)matchedLines.item(i);
   
                    // Display the title
                    System.out.println(book.getTextContent());
   
                }
            }
   
            // If no books were found, say so
            if (!found) {
                System.err.println("No books were found matching the criteria");
            }
   
            // Finish
            System.out.println("Finished.");
        }

Thanks and best regards
Alix
------------------------------------------------------------------------------ Sell apps to millions through the Intel(R) Atom(Tm) Developer Program Be part of this innovative community and reach millions of netbook users worldwide. Take advantage of special opportunities to increase revenue and speed time-to-market. Join now, and jumpstart your future. http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________ saxon-help mailing list archived at http://saxon.markmail.org/


------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users
worldwide. Take advantage of special opportunities to increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-help@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help

------------------------------------------------------------------------------ Sell apps to millions through the Intel(R) Atom(Tm) Developer Program Be part of this innovative community and reach millions of netbook users worldwide. Take advantage of special opportunities to increase revenue and speed time-to-market. Join now, and jumpstart your future. http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________ saxon-help mailing list archived at http://saxon.markmail.org/ saxon-help@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/saxon-help