Michael,

Thanks for the reply.

I've included my complete test program below. The test only works with the Xerces XMLSchemaFactory if I clone the schema document element each time before it is wrapped by a DOMSource. Is this the expected behavior? I find it interesting that the JDK 1.5 SchemaFactory does not require the schema document element to be cloned? Can you explain the discrepancy?

- Ron

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class TestDOMValidation {

    {
        System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
            "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
        System.setProperty("javax.xml.parsers.SAXParserFactory",
            "org.apache.xerces.jaxp.SAXParserFactoryImpl");
    }
   
    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println ("Usage: java TestDOMValidation " +
                                "[xml filename] [schema filename1] [schema filename2] ...");
            System.exit (1);
        }

        try {
            // Get Document Builder Factory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   
            // Leave off validation, and turn off namespaces
            factory.setValidating(false);
            factory.setNamespaceAware(true);
           
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File(args[0]));
           
            Document[] schemaDocs = new Document[args.length - 1];
            Source[] constraints = new Source[args.length - 1];
            for (int j = 1; j < args.length; j++) {
                String schemaFilename = args[j];
                schemaDocs[j - 1] = builder.parse(new File(schemaFilename));
            }
           
            SchemaFactory constraintFactory =
                SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            for (int i = 0; i < 2; i++) {
       
                for (int j = 1; j < args.length; j++) {
                    Node docRoot = schemaDocs[j - 1].getDocumentElement();
                    // The docRoot node must be cloned in order for this test work using the Xerces XMLSchemaFactory
                    // The clone is not required using the JAXP 1.3 SchemaFactoryImpl
                    docRoot = docRoot.cloneNode(true);
                    constraints[j - 1] = new DOMSource(docRoot);
                }
   
                // Handle validation
                Schema schema = constraintFactory.newSchema(constraints);
                Validator validator = schema.newValidator();
   
                // Validate the DOM tree
                try {
                    validator.validate(new DOMSource(doc));
                    System.out.println("Document validates fine.");
                } catch (org.xml.sax.SAXException e) {
                    System.out.println("Validation error: " + e.getMessage());
                }
            }
        } catch (ParserConfigurationException e) {
            System.out.println("The underlying parser does not support the requested features.");
        } catch (FactoryConfigurationError e) {
            System.out.println("Error occurred obtaining Document Builder Factory.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Michael Glavassevich wrote:
You're calling newSchema() twice with the same list of Source objects. In 
general Sources are not reusable. For instance, if they contain 
InputStreams or Readers they will have been consumed by the first call to 
newSchema().

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: [EMAIL PROTECTED]
E-mail: [EMAIL PROTECTED]

Ron Gavlin <[EMAIL PROTECTED]> wrote on 09/16/2006 12:13:37 AM:

  
FYI, I did some testing on Sun JDK1.5.0_07 w/Xerces 2.8.0 on the 
Win32 platform. If I set -Djavax.xml.validation.SchemaFactory:http:

    
//www.w3.org/2001/XMLSchema=org.apache.xerces.jaxp.validation.XMLSchemaFactory
  
, the erroneous SAXParseException is generated. However, if I use 
the the default JDK 1.5 SchemaFactory, com.sun.org.apache.xerces.
internal.jaxp.validation.xs.SchemaFactoryImpl, the problem 
disappears. I hope that helps isolate the problem. Does anyone have 
a suggested workaround for running on a 1.4 JDK?

Thanks in advance.

- Ron

----- Original Message ----
From: Ron Gavlin <[EMAIL PROTECTED]>
To: [email protected]
Sent: Thursday, September 14, 2006 3:24:56 PM
Subject: Bogus schema generated after multiple invocations of 
SchemaFactory.newInstance(W3C_...).newSchema(Source[] ...)

Greetings,

I am using Sun JDK1.4.2_11 w/Xerces 2.8.0 on the Win32 platform. 

I have the following sample code which works fine:

...
Source[] xsdSources = ...;
Document xmlDocument = ...;
Schema schema = SchemaFactory.newInstance(XMLConstants.
W3C_XML_SCHEMA_NS_URI).newSchema(xsdSources);
Validator validator = schema.newValidator();
validator.validate(new DOMSource(xmlDocument.getDocumentElement()));

If I modify the code to look like that listed below (note the add'l 
newSchema invocation), I receive the following SAXParseException: 
cvc-elt.1: Cannot find the declaration of element 'myGlobalElement'.

...
Source[] xsdSources=...;
Document xmlDocument = ...;
Schema schema = SchemaFactory.newInstance(XMLConstants.
W3C_XML_SCHEMA_NS_URI).newSchema(xsdSources);
schema = SchemaFactory.newInstance(XMLConstants.
W3C_XML_SCHEMA_NS_URI).newSchema(xsdSources);
Validator validator = schema.newValidator();
validator.validate(new DOMSource(xmlDocument.getDocumentElement()));

In the debugger, I noticed that the schema generated by the first 
newSchema invocation contains a SchemaGrammar whose fGlobalElemDecls
contains entries for all my global elements. However, after the 
second newSchema invocation, the SchemaGrammar in the newly 
constructed schema has a fGlobalElemDecls data structure with all 
null entries. This would explain the SAXParseException in the second
example above.

The schemas in my production application change on the fly. When one
changes, I need to invoke newSchema to build a new Schema to use for
validation. This is not working. 

Thanks in advance for your help.

- Ron

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
    

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


  

Reply via email to