C में संदर्भित XSD के विरुद्ध XML को मान्य करना


161

मेरे पास इस तरह के एक निर्दिष्ट स्कीमा स्थान के साथ एक XML फ़ाइल है:

xsi:schemaLocation="someurl ..\localSchemaPath.xsd"

मैं C # में सत्यापन करना चाहता हूं। विजुअल स्टूडियो, जब मैं फ़ाइल खोलता हूं, तो यह स्कीमा के खिलाफ मान्य होता है और त्रुटियों को पूरी तरह से सूचीबद्ध करता है। किसी तरह, हालांकि, मैं सी # में इसे स्वचालित रूप से मान्य करने के लिए ऐसा करने के लिए स्कीमा को निर्दिष्ट किए बिना निर्दिष्ट करने के लिए प्रतीत नहीं कर सकता:

XmlDocument asset = new XmlDocument();

XmlTextReader schemaReader = new XmlTextReader("relativeSchemaPath");
XmlSchema schema = XmlSchema.Read(schemaReader, SchemaValidationHandler);

asset.Schemas.Add(schema);

asset.Load(filename);
asset.Validate(DocumentValidationHandler);

क्या मुझे XML फ़ाइल में निर्दिष्ट स्कीमा के साथ स्वतः पुष्टि करने में सक्षम नहीं होना चाहिए? मैं क्या खो रहा हूँ ?


1
MSDN नमूना देखें: msdn.microsoft.com/en-us/library/…

जवाबों:


167

आपको एक XmlReaderSettings उदाहरण बनाने और अपने XmlReader को पास करने की आवश्यकता है जब आप इसे बनाते हैं। फिर आप ValidationEventHandlerसत्यापन त्रुटियों को प्राप्त करने के लिए सेटिंग्स में सदस्यता ले सकते हैं। आपका कोड इस तरह दिखाई देगा:

using System.Xml;
using System.Xml.Schema;
using System.IO;

public class ValidXSD
{
    public static void Main()
    {

        // Set the validation settings.
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

        // Create the XmlReader object.
        XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);

        // Parse the file. 
        while (reader.Read()) ;

    }
    // Display any warnings or errors.
    private static void ValidationCallBack(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);
        else
            Console.WriteLine("\tValidation error: " + args.Message);

    }
}

4
+1 हालाँकि usingपूर्णता के लिए क्लॉज़ का उपयोग करने के लिए अद्यतन करना चाहिए :)
IAbstract

55
यदि आप एक XSD फ़ाइल से तुलना करना चाहते हैं, तो उपरोक्त कोड में निम्न पंक्ति जोड़ें: settings.Schemas.Add ("YourDomainHere", "yourXSDFile.xsd");
जेफ फोल

5
त्रुटि का लाइन # और स्थिति # उपयोग करने के लिए: args.Exception.LineNumber ... ValidationCallBack में
user610064

1
अगर स्कीमा मेरे पास नाम स्थान नहीं है तो क्या होगा?
पेड़

1
लैम्ब्डा , बेहतर IMHO, अधिक स्पष्टता कोड का उपयोग करनाsettings.ValidationEventHandler += (o, args) => { errors = true; // More code };
Kiquenet

107

एक आसान तरीका है, यदि आप .NET 3.5 का उपयोग कर रहे हैं, तो उपयोग XDocumentऔर XmlSchemaSetसत्यापन करना है।

XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(schemaNamespace, schemaFileName);

XDocument doc = XDocument.Load(filename);
string msg = "";
doc.Validate(schemas, (o, e) => {
    msg += e.Message + Environment.NewLine;
});
Console.WriteLine(msg == "" ? "Document is valid" : "Document invalid: " + msg);

अधिक सहायता के लिए MSDN प्रलेखन देखें ।


2
इस विधि के लिए आपको xml से इनलाइन स्कीमा लेने के बजाय स्कीमा को पहले से जानना आवश्यक है।
लंकिमार्ट

यह ठीक काम करता है लेकिन त्रुटि तब फेंकता है जब xml दस्तावेज़ में कुछ HTML टैग होते हैं जैसे <कैटलॉग> मेरा <i> नया </ i> कैटलॉग .... </ कैटलॉग> उपरोक्त मामले में html टैग जैसे "<i>" एक समस्या बनाता है। यह "<कैटलॉग>" का मूल्य है ... इसे कैसे मान्य किया जाए
अनिल पुरस्वानी

6
@AnilPurswani: यदि आप HTML को XML दस्तावेज़ में रखना चाहते हैं, तो आपको इसे CDATA में लपेटना होगा। <catalog><![CDATA[my <i> new </i> catalog....]]></catalog>ऐसा करने का सही तरीका है।
p0lar_bear

सरल और सुरुचिपूर्ण! जब एक निश्चित स्कीमा सेट (जो हमारा मामला है, और एक से अधिक फ़ोल्डरों और फ़ाइलों के साथ एक बड़ा) के खिलाफ मान्य होने पर यह बहुत अच्छी तरह से काम करता है। मैं पहले से ही Validator पर कॉल के बीच पुनः उपयोग किए जाने वाले XmlSchemaSet को कैच करने के बारे में सोच रहा हूं। आपका बहुत बहुत धन्यवाद!
एडेल रेटामल जूल

20

निम्न उदाहरण XML फ़ाइल को मान्य करता है और उचित त्रुटि या चेतावनी उत्पन्न करता है।

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;

public class Sample
{

    public static void Main()
    {
        //Load the XmlSchemaSet.
        XmlSchemaSet schemaSet = new XmlSchemaSet();
        schemaSet.Add("urn:bookstore-schema", "books.xsd");

        //Validate the file using the schema stored in the schema set.
        //Any elements belonging to the namespace "urn:cd-schema" generate
        //a warning because there is no schema matching that namespace.
        Validate("store.xml", schemaSet);
        Console.ReadLine();
    }

    private static void Validate(String filename, XmlSchemaSet schemaSet)
    {
        Console.WriteLine();
        Console.WriteLine("\r\nValidating XML file {0}...", filename.ToString());

        XmlSchema compiledSchema = null;

        foreach (XmlSchema schema in schemaSet.Schemas())
        {
            compiledSchema = schema;
        }

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Schemas.Add(compiledSchema);
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
        settings.ValidationType = ValidationType.Schema;

        //Create the schema validating reader.
        XmlReader vreader = XmlReader.Create(filename, settings);

        while (vreader.Read()) { }

        //Close the reader.
        vreader.Close();
    }

    //Display any warnings or errors.
    private static void ValidationCallBack(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);
        else
            Console.WriteLine("\tValidation error: " + args.Message);

    }
}

पूर्ववर्ती उदाहरण निम्नलिखित इनपुट फ़ाइलों का उपयोग करता है।

<?xml version='1.0'?>
<bookstore xmlns="urn:bookstore-schema" xmlns:cd="urn:cd-schema">
  <book genre="novel">
    <title>The Confidence Man</title>
    <price>11.99</price>
  </book>
  <cd:cd>
    <title>Americana</title>
    <cd:artist>Offspring</cd:artist>
    <price>16.95</price>
  </cd:cd>
</bookstore>

books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="urn:bookstore-schema"
    elementFormDefault="qualified"
    targetNamespace="urn:bookstore-schema">

 <xsd:element name="bookstore" type="bookstoreType"/>

 <xsd:complexType name="bookstoreType">
  <xsd:sequence maxOccurs="unbounded">
   <xsd:element name="book"  type="bookType"/>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:complexType name="bookType">
  <xsd:sequence>
   <xsd:element name="title" type="xsd:string"/>
   <xsd:element name="author" type="authorName"/>
   <xsd:element name="price"  type="xsd:decimal"/>
  </xsd:sequence>
  <xsd:attribute name="genre" type="xsd:string"/>
 </xsd:complexType>

 <xsd:complexType name="authorName">
  <xsd:sequence>
   <xsd:element name="first-name"  type="xsd:string"/>
   <xsd:element name="last-name" type="xsd:string"/>
  </xsd:sequence>
 </xsd:complexType>

</xsd:schema>

18

व्यक्तिगत रूप से मैं कॉलबैक के बिना मान्य करने का पक्ष लेता हूं:

public bool ValidateSchema(string xmlPath, string xsdPath)
{
    XmlDocument xml = new XmlDocument();
    xml.Load(xmlPath);

    xml.Schemas.Add(null, xsdPath);

    try
    {
        xml.Validate(null);
    }
    catch (XmlSchemaValidationException)
    {
        return false;
    }
    return true;
}

( सिंक्रोनस XML स्कीमा सत्यापन में टिमिज़0r का पद देखें । .NET 3.5 )


9
कॉलबैक आपको कुछ अतिरिक्त जानकारी प्रदान करता है कि आपके xml में कौन सी लाइन सही नहीं है। यह विधि बहुत ही द्विआधारी है, या तो सही या गलत :)
FrankyHollywood

13

मैंने वीबी में इस तरह का स्वचालित सत्यापन किया था और इसी तरह मैंने इसे (सी # में परिवर्तित) किया था:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = settings.ValidationFlags |
                           Schema.XmlSchemaValidationFlags.ProcessSchemaLocation;
XmlReader XMLvalidator = XmlReader.Create(reader, settings);

फिर मैंने settings.ValidationEventHandlerफ़ाइल को पढ़ते हुए ईवेंट की सदस्यता ली ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.