简体   繁体   中英

How to validate 1 XML file against 2 XSD's?

I need a user-supplied XML file to match 1 of 2 possible schemas.

Following along this tutorial, as our "real" XSD's aren't finished yet:

https://msdn.microsoft.com/en-us/library/bb387037.aspx

Except I want the "inverse" of that tutorial. So I modified it so that there's a second xsdMarkup :

static void Main(string[] args)
{
    string xsdMarkup1 = CreateXsd(2);
    string xsdMarkup2 = CreateXsd(3);

    XmlSchemaSet schemas = new XmlSchemaSet();
    schemas.Add("", XmlReader.Create(new StringReader(xsdMarkup1)));
    schemas.Add("", XmlReader.Create(new StringReader(xsdMarkup2)));

    XDocument doc1 = CreateXDoc(2);
    XDocument doc2 = CreateXDoc(3);

    Validate(doc1, schemas);
    Validate(doc2, schemas);

    Console.ReadLine();
}

Expected Output : Both should validate as the first schema supports Child1 Child2 , and the second schema supports Child1 , Child3 .

The methods CreateXsd , CreateXDoc , and Validate just contain the code that was there from the tutorial. The int I pass to it just gets appended to the second Child element so you have Child1 and either Child2 or Child3 as the second element, depending on what's passed.

When I run this, Validate(doc1, schemas); crashes with this error:

The global element 'Root' has already been declared.

It seems like because my two xsdMarkup variables use the same xmlns value, it's simply appending the schema to the first schema. OK, no problem, I'll just change the namespace for the second one... Nope; that crashes because the URL isn't valid and I don't know what I could substitute instead.

So, hypothetically, say I had two functioning schemas. Can I call XmlSchemaSet.Add twice then call XDocument.Validate(myXmlSchemaSetObj, someValidationEventHandlerDefintion); to validate 1 file against multiple schemas?

I think it fails for you because you specify "" as the targetNamespace both times. It sounds like you are still developing this project, so we can get you "patched up for the show" by breaking-out the logic a bit for now.

PS You can also try passing a null value instead of "" as the targetNameSpace in your code above...maybe that would work, too!

static void Main(string[] args)
{
    string xsdMarkup1 = CreateXsd(2);
    string xsdMarkup2 = CreateXsd(3);

    XmlSchemaSet schemas1 = new XmlSchemaSet();
    schemas1.Add("", XmlReader.Create(new StringReader(xsdMarkup1)));
    XmlSchemaSet schemas2 = new XmlSchemaSet();
    schemas2.Add("", XmlReader.Create(new StringReader(xsdMarkup2)));

    XDocument doc1 = CreateXDoc(2);
    XDocument doc2 = CreateXDoc(3);

    Validate(doc1, schemas1);
    Validate(doc1, schemas2);
    Validate(doc2, schemas1);
    Validate(doc2, schemas2);

    Console.ReadLine();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM