4

I am working on a project where we want to validate data against xsd schema, tricky part is data can be coming from same source in the form of json, xml etc. I have figured out how to get it to validate against xml. I haven't been able to do the same for JSON. I am trying to avoid having both json schema as well as xml schema. To do so I am converting my json file into a XmlDocument like this;

using (var r = new StreamReader(xmlFileSource))
{
    var json = r.ReadToEnd();

    var xd = (XmlDocument)JsonConvert.DeserializeXmlNode(
        json.ToString(CultureInfo.InvariantCulture), fileName);
}

I can't find a way to validate XmlDocument against an xsd file. Any help will be much appreciated, or if you have any recommendation to achieve the same task in a better way.

Thanks!

Craig W.
  • 17,838
  • 6
  • 49
  • 82
OBL
  • 1,347
  • 10
  • 24
  • 45
  • possible duplicate of [How to validate an XML document?](http://stackoverflow.com/questions/3465335/how-to-validate-an-xml-document) – Edin May 27 '14 at 17:21
  • @Edin No, this is not a duplicate of that, OP is trying to validate Json using XML schema. – DavidG May 27 '14 at 17:27
  • Thanks for the help. I am using referenced way to validate Xml document. But can't seem to figure out how to use for Json. Correct me if I am wrong but the mentioned code deals with files but not with an object of type XmlDocument? – OBL May 27 '14 at 17:34
  • @DavidG: You are right. That made me post a working sample :) Hope it helps... – Edin May 27 '14 at 18:40
  • Json and xml are not interchangeable in way which extends to schema validation. – tom redfern May 27 '14 at 18:44

2 Answers2

6

Although Mark was faster, I will post this, since it is a bit different - it does not require loading XmlDocument again into stream and it has a full working example:

        XmlDocument xml = new XmlDocument();
        xml.LoadXml(@"<?xml version=""1.0"" encoding=""UTF-8""?>
            <shiporder orderid=""889923"">
                <orderperson>John Smith</orderperson>
                <shipto>
                    <name>Ola Nordmann</name>
                    <address>Langgt 23</address>
                    <city>4000 Stavanger</city>
                    <country>Norway</country>
                </shipto>
            </shiporder>");

        xml.Schemas.Add(null, "schema.xsd");
        xml.Validate((sender, args) =>
        {
            switch (args.Severity)
            {
                case XmlSeverityType.Error:
                    Console.WriteLine("XML is invalid: {0}", args.Exception);
                    break;
                case XmlSeverityType.Warning:
                    // handle warning
                    ;
                    break;
            }
        });

schema.xsd has the following content:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="shiporder">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="orderperson" type="xs:string"/>
                <xs:element name="shipto">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string"/>
                            <xs:element name="address" type="xs:string"/>
                            <xs:element name="city" type="xs:string"/>
                            <xs:element name="country" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="orderid" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

You can test validation, by making your xml invalid, e.g. removing element <orderperson>.

Obviously, you don't need to load XmlDocument, since you already have it and path to your schema must be adapted.

Edin
  • 1,476
  • 11
  • 21
2

Building on the accepted answer to a similar question, and accepting that this approach is inefficient and might pose memory use challenge:

XmlReaderSettings settings = new XmlReaderSettings();

settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add ( .... );  // assumes XSD already available
settings.ValidationEventHandler += delegate( object sender, ValidationEventArgs e )
{
     DoSomethingAboutSchemaNoncompliance(e.Message);
};

// Get a stream from the XML document for use in schema validation.
XmlReader reader = XmlReader.Create(xd.Save(new System.IO.MemoryStream()), settings);
Community
  • 1
  • 1
Mark Larter
  • 2,343
  • 1
  • 27
  • 34