I finally figured it out.
First of all, in the foo schema, the bar-config and baz-config elements are of a type that includes the any element, for example:
<sequence> <any minOccurs="0" maxOccurs="1" processContents="lax" namespace="##any" /> </sequence>
In xml, then you must specify the correct namespace using the xmlns attribute of the child element bar-config or baz-config, for example:
<bar-config> <config xmlns="http://www.example.org/bar/Alpha"> ... config xml here ... </config> </bar-config>
Then your XML Schema file for bar Alpha will have the target namespace http://www.example.org/bar/Alpha and will define the root element of config .
If your XML file has namespace declarations and schema locations for both schema files, this is enough for the editor to do the whole check (at least enough for Eclipse).
So far, we have satisfied the requirement that the xml author can write xml so that it is validated in the editor.
Now we need the consumer to check. In my case, I use Java.
If you accidentally know the schema files that you need to use for verification in advance, then you simply create one Schema object and validate as usual:
Schema schema = factory().newSchema(new Source[] { new StreamSource(stream("foo.xsd")), new StreamSource(stream("Alpha.xsd")), new StreamSource(stream("Mercury.xsd")), });
In this case, however, we do not know which xsd files should be used until we analyze the main document. So, the general procedure is as follows:
- Validate xml using only the main (foo) scheme
- Define the schema used to validate part of the document.
- Find the node that is the root of the part to test with a separate schema
- Import node into a new document
- Validate new document with another schema file
Caution: it seems that the document should be created for use in the namespace for this to work.
Here is some code (this was torn from different places in my code, so some errors may occur when copying and pasting):
// Contains the filename of the xml file String filename; // Load the xml data using a namespace-aware builder (the method // 'stream' simply opens an input stream on a file) Document document; DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setNamespaceAware(true); document = docBuilderFactory.newDocumentBuilder().parse(stream(filename)); // Create the schema factory SchemaFactory sFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); // Load the main schema Schema schema = sFactory.newSchema( new StreamSource(stream("foo.xsd"))); // Validate using main schema schema.newValidator().validate(new DOMSource(document)); // Get the node that is the root for the portion you want to validate // using another schema Node node= getSpecialNode(document); // Build a Document from that node Document subDocument = docBuilderFactory.newDocumentBuilder().newDocument(); subDocument.appendChild(subDocument.importNode(node, true)); // Determine the schema to use using your own logic Schema subSchema = parseAndDetermineSchema(document); // Validate using other schema subSchema.newValidator().validate(new DOMSource(subDocument));