XML to validate multiple xsd schemas

I am writing xsd and verification code, so I have excellent control.

I would like to have a download tool that adds material to my application based on an XML file. One part of the XML file must be checked against different schemas based on one of the values ​​in the other part. Here is an example to illustrate:

<foo> <name>Harold</name> <bar>Alpha</bar> <baz>Mercury</baz> <!-- ... more general info that applies to all foos ... --> <bar-config> <!-- the content here is specific to the bar named "Alpha" --> </bar-config> <baz-config> <!-- the content here is specific to the baz named "Mercury" --> </baz> </foo> 

In this case, there is some controlled vocabulary for the <bar> content, and I can handle this part just fine. Then, based on the value of the stroke, the appropriate xml scheme should be used to check the contents of bar-config. Similarly for baz and baz-config.

The code that parses / validates is written in Java. Not sure how much the language depends on the solution.

Ideally, the solution will allow the xml author to declare the appropriate locations of the circuit and something is wrong so that he / she can get the xml checked on the fly in a fairly intelligent editor.

In addition, the possible values ​​for <bar> and <baz> are orthogonal, so I do not want to do this by extension for all possible combinations of bar / baz. I mean, if there are 24 possible values ​​/ schemes of the bar and 8 possible values ​​/ schemes of baz, I want to be able to write 1 + 24 + 8 = 33 general schemes instead of 1 * 24 * 8 = 192 general schemes.

In addition, I would prefer NOT to break bar-config and baz-config into separate XML files if possible. I understand that this can make all the problems much easier, since each xml file will have one scheme, but I'm trying to figure out if there is a good solution for one xml file.

+4
source share
4 answers

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)); 
+6
source

Take a look at NVDL (Name Based Validation Distribution Language) - http://www.nvdl.org/

It is designed to do what you want to do (check parts of an XML document that have their own namespaces and schemas).

There is a tutorial here - http://www.dpawson.co.uk/nvdl/ - and a Java implementation here - http://jnvdl.sourceforge.net/

Hope this helps! Kevin

+2
source

You need to define a target namespace for each individually verified part of the document instance. Then you define a master schema that uses <xsd:include> to reference the schema documents for these components.

The limitation with this approach is that you cannot allow individual components to define the circuits that should be used to test them. But it’s a bad idea in general to let the document tell you how to check it (i.e. Validation must have something that controls your application).

0
source

You can also use the "resource resolver" to allow the "xml authors" to specify their own schema file, at least to some extent, for example: https://stackoverflow.com/a/167268/2776, at the end of the day, you need a fully compatible An XML file, which in any case can be checked using ordinary tools :)

0
source

All Articles