Validate unknown xml against multiple schemas until match is found

c#, linq-to-xml, xml, xsd

Solution

First, you have to figure out what XSD files can be put together in a file set. The error you're getting tells you that the same element 'interface' has definitions coming from two or more different base URIs.

If you want to determine the sets dynamically, then you're in for a bit of work. It is possible, but it's not trivial. It depends whether the XSD files use composition (include/import/redefine). If they don't (the easy scenario), then in order to put XSD files together you have to load each XSD file individually, build an index of all globally defined content (types, elements, groups, attributes, attribute groups) then put together those in sets such that given any pair of individual XSD members of the set, the intersection set is empty. The strategy to build a set depends on many factors, performance and coverage being just two. Based on this trivial case, you can see how composition becomes important, since now even when the intersection is not empty, for all intents is to be considered empty if the common content comes from the same URI.

QTAssistant (I am associated with it) has a whole engine to deal with the above in order to set up XML Schema source sets (or collections) for its XML Schema Refactoring engine, when "harvesting" arbitrary XSD content for analysis, validation, etc.

Once you have the sets figured out, you'll have to make assumptions vis-a-vis the make up of those schemas. In other words, what constitutes the set of valid XML document elements (sometimes not all global element definitions are valid document elements), and what schema set is supposed to be used for each document element. It is clear that you must deal with this somehow, since you have duplicate elements.

If you want to handle it as per your question, then simply loop through the set of schema sets constructed as above.

The best way to come up with a strategy on how to figure out the best sets manually, may be to visualize the relationships between your XSD files. Below is an illustration of how I see it with the tools available to me, from another post here on SO.

Problem

I have xml sent to a web page and I would like to validate against several xsd's, until the file validates. When it validates I would then de able to determine the type of xml file based on what schema managed to validate it. ``` List<string> xsdList = new List<string>(); xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Enquiry.xsd"); xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\FingerDeleted.xsd"); xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Heartbeat.xsd"); xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Validation.xsd"); XmlSchemaSet schemas = new XmlSchemaSet(); foreach (string schema in xsdList) { var reader = new StringReader(File.ReadAllText(schema)); schemas.Add("", XmlReader.Create(reader)); } request.Validate(schemas, (o, e) => { match = false; }); ``` Can anyone help, the above is what ive cobbled together so far, it currently throws an error 'System.Xml.Schema.XmlSchemaValidationException: The global element 'interface' has already been declared' is there a way to get a return of which schema valiation was a success?

Original source