Dela via


Verifiera ett XML-dokument i DOM

KlassenXmlDocument validerar inte XML i dokumentobjektmodellen (DOM) mot ett XML-schemadefinitionsspråk (XSD) schema eller dokumenttypsdefinition (DTD) som standard. XML-koden är endast verifierad för att vara välformulerad.

Om du vill verifiera XML-koden i DOM kan du verifiera XML-koden när den läses in i DOM genom att skicka ett schemaverifierande XmlReader till Load-metoden för klassen XmlDocument eller verifiera ett tidigare ovaliderat XML-dokument i DOM med hjälp av Validate-metoden för klassen XmlDocument.

Validera ett XML-dokument när det läses in i DOM

Klassen XmlDocument validerar XML-data när de läses in i DOM när en verifierande XmlReader skickas till Load-metoden för klassen XmlDocument.

Efter valideringen tillämpas schemastandardvärden, textvärden konverteras till atomiska värden efter behov och typinformation associeras med verifierade informationsobjekt. Därför ersätter inskrivna XML-data tidigare otypade XML-data.

Skapa en XML-Schema-Validating XmlReader

Skapa ett XML-schema som validerar XmlReadergenom att följa dessa steg.

  1. Skapa en ny XmlReaderSettings instans.

  2. Lägg till ett XML-schema i egenskapen Schemas för XmlReaderSettings-instansen.

  3. Ange Schema som ValidationType.

  4. Du kan också ange ValidationFlags och en ValidationEventHandler för att hantera schemavalideringsfel och varningar som påträffades under valideringen.

  5. Skicka slutligen XmlReaderSettings-objektet till Create-metoden för klassen XmlReader tillsammans med XML-dokumentet, vilket skapar ett schemaverifierande XmlReader.

Exempel

I kodexemplet som följer validerar en schemaverifierande XmlReader det XML-data som läses in i DOM. Ogiltiga ändringar görs i XML-dokumentet och dokumentet återkallas sedan, vilket orsakar schemavalideringsfel. Slutligen korrigeras ett av felen och sedan verifieras en del av XML-dokumentet delvis.

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

class XmlDocumentValidationExample
{
    static void Main(string[] args)
    {
        try
        {
            // Create a schema validating XmlReader.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
            settings.ValidationFlags = settings.ValidationFlags | XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);

            // The XmlDocument validates the XML document contained
            // in the XmlReader as it is loaded into the DOM.
            XmlDocument document = new XmlDocument();
            document.Load(reader);

            // Make an invalid change to the first and last
            // price elements in the XML document, and write
            // the XmlSchemaInfo values assigned to the price
            // element during load validation to the console.
            XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
            manager.AddNamespace("bk", "http://www.contoso.com/books");

            XmlNode priceNode = document.SelectSingleNode(@"/bk:bookstore/bk:book/bk:price", manager);

            Console.WriteLine($"SchemaInfo.IsDefault: {priceNode.SchemaInfo.IsDefault}");
            Console.WriteLine($"SchemaInfo.IsNil: {priceNode.SchemaInfo.IsNil}");
            Console.WriteLine($"SchemaInfo.SchemaElement: {priceNode.SchemaInfo.SchemaElement}");
            Console.WriteLine($"SchemaInfo.SchemaType: {priceNode.SchemaInfo.SchemaType}");
            Console.WriteLine($"SchemaInfo.Validity: {priceNode.SchemaInfo.Validity}");

            priceNode.InnerXml = "A";

            XmlNodeList priceNodes = document.SelectNodes(@"/bk:bookstore/bk:book/bk:price", manager);
            XmlNode lastprice = priceNodes[priceNodes.Count - 1];

            lastprice.InnerXml = "B";

            // Validate the XML document with the invalid changes.
            // The invalid changes cause schema validation errors.
            document.Validate(ValidationEventHandler);

            // Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99";

            // Validate only the first book element. The last book
            // element is invalid, but not included in validation.
            XmlNode bookNode = document.SelectSingleNode(@"/bk:bookstore/bk:book", manager);
            document.Validate(ValidationEventHandler, bookNode);
        }
        catch (XmlException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlException: {ex.Message}");
        }
        catch(XmlSchemaValidationException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlSchemaValidationException: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.Exception: {ex.Message}");
        }
    }

    static void ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("\nWARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("\nERROR: ");

        Console.WriteLine(args.Message);
    }
}
Imports System.Xml
Imports System.Xml.Schema

Class XmlDocumentValidationExample

    Shared Sub Main()

        Try

            ' Create a schema validating XmlReader.
            Dim settings As XmlReaderSettings = New XmlReaderSettings()
            settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
            AddHandler settings.ValidationEventHandler, New ValidationEventHandler(AddressOf ValidationEventHandler)
            settings.ValidationFlags = settings.ValidationFlags And XmlSchemaValidationFlags.ReportValidationWarnings
            settings.ValidationType = ValidationType.Schema

            Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)

            ' The XmlDocument validates the XML document contained
            ' in the XmlReader as it is loaded into the DOM.
            Dim document As XmlDocument = New XmlDocument()
            document.Load(reader)

            ' Make an invalid change to the first and last 
            ' price elements in the XML document, and write
            ' the XmlSchemaInfo values assigned to the price
            ' element during load validation to the console.
            Dim manager As XmlNamespaceManager = New XmlNamespaceManager(document.NameTable)
            manager.AddNamespace("bk", "http://www.contoso.com/books")

            Dim priceNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book/bk:price", manager)

            Console.WriteLine("SchemaInfo.IsDefault: {0}", priceNode.SchemaInfo.IsDefault)
            Console.WriteLine("SchemaInfo.IsNil: {0}", priceNode.SchemaInfo.IsNil)
            Console.WriteLine("SchemaInfo.SchemaElement: {0}", priceNode.SchemaInfo.SchemaElement)
            Console.WriteLine("SchemaInfo.SchemaType: {0}", priceNode.SchemaInfo.SchemaType)
            Console.WriteLine("SchemaInfo.Validity: {0}", priceNode.SchemaInfo.Validity)

            priceNode.InnerXml = "A"

            Dim priceNodes As XmlNodeList = document.SelectNodes("/bk:bookstore/bk:book/bk:price", manager)
            Dim lastprice As XmlNode = priceNodes(priceNodes.Count - 1)

            lastprice.InnerXml = "B"

            ' Validate the XML document with the invalid changes.
            ' The invalid changes cause schema validation errors.
            document.Validate(AddressOf ValidationEventHandler)

            ' Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99"

            ' Validate only the first book element. The last book
            ' element is invalid, but not included in validation.
            Dim bookNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book", manager)
            document.Validate(AddressOf ValidationEventHandler, bookNode)

        Catch ex As XmlException
            Console.WriteLine("XmlDocumentValidationExample.XmlException: {0}", ex.Message)

        Catch ex As XmlSchemaValidationException
            Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message)

        Catch ex As Exception
            Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", ex.Message)

        End Try

    End Sub

    Shared Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)

        If args.Severity = XmlSeverityType.Warning Then
            Console.Write(vbCrLf & "WARNING: ")
        Else
            If args.Severity = XmlSeverityType.Error Then
                Console.Write(vbCrLf & "ERROR: ")
            End If
        End If
        Console.WriteLine(args.Message)

    End Sub

End Class

Exemplet tar contosoBooks.xml-filen som indata.

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

I exemplet används även contosoBooks.xsd-filen som indata.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Tänk på följande när du verifierar XML-data när de läses in i DOM.

  • I exemplet ovan anropas ValidationEventHandler när en ogiltig typ påträffas. Om en ValidationEventHandler inte har angetts för valideringen XmlReadergenereras en XmlSchemaValidationException när Load anropas om någon attribut- eller elementtyp inte matchar motsvarande typ som anges i valideringsschemat.

  • När ett XML-dokument läses in i ett XmlDocument objekt med ett associerat schema som definierar standardvärden, behandlar XmlDocument dessa standardvärden som om de visades i XML-dokumentet. Det innebär att egenskapen IsEmptyElement alltid returnerar false för ett element som standard från schemat. Även om det i XML-dokumentet skrevs som ett tomt element.

Validera ett XML-dokument i DOM

Validate-metoden för klassen XmlDocument validerar XML-data som lästs in i DOM mot scheman i XmlDocument-objektets egenskap Schemas. Efter valideringen tillämpas schemastandardvärden, textvärden konverteras till atomiska värden efter behov och typinformation associeras med verifierade informationsobjekt. Därför ersätter inskrivna XML-data tidigare otypade XML-data.

Exemplet nedan liknar exemplet i "Validera ett XML-dokument när det läses in i DOM" ovan. I det här exemplet verifieras inte XML-dokumentet eftersom det läses in i DOM, utan verifieras i stället efter att det har lästs in i DOM med hjälp av metoden Validate för klassen XmlDocument. Metoden Validate verifierar XML-dokumentet mot XML-scheman som finns i egenskapen Schemas för XmlDocument. Ogiltiga ändringar görs sedan i XML-dokumentet och dokumentet återkallas sedan, vilket orsakar schemavalideringsfel. Slutligen korrigeras ett av felen och sedan verifieras en del av XML-dokumentet delvis.

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

class XmlDocumentValidationExample
{
    static void Main(string[] args)
    {
        try
        {
            // Create a new XmlDocument instance and load
            // the XML document into the DOM.
            XmlDocument document = new XmlDocument();
            document.Load("contosoBooks.xml");

            // Add the XML schema for the XML document to the
            // Schemas property of the XmlDocument.
            document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");

            // Validate the XML document loaded into the DOM.
            document.Validate(ValidationEventHandler);

            // Make an invalid change to the first and last
            // price elements in the XML document, and write
            // the XmlSchemaInfo values assigned to the price
            // element during validation to the console.
            XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
            manager.AddNamespace("bk", "http://www.contoso.com/books");

            XmlNode priceNode = document.SelectSingleNode(@"/bk:bookstore/bk:book/bk:price", manager);

            Console.WriteLine($"SchemaInfo.IsDefault: {priceNode.SchemaInfo.IsDefault}");
            Console.WriteLine($"SchemaInfo.IsNil: {priceNode.SchemaInfo.IsNil}");
            Console.WriteLine($"SchemaInfo.SchemaElement: {priceNode.SchemaInfo.SchemaElement}");
            Console.WriteLine($"SchemaInfo.SchemaType: {priceNode.SchemaInfo.SchemaType}");
            Console.WriteLine($"SchemaInfo.Validity: {priceNode.SchemaInfo.Validity}");

            priceNode.InnerXml = "A";

            XmlNodeList priceNodes = document.SelectNodes(@"/bk:bookstore/bk:book/bk:price", manager);
            XmlNode lastprice = priceNodes[priceNodes.Count - 1];

            lastprice.InnerXml = "B";

            // Validate the XML document with the invalid changes.
            // The invalid changes cause schema validation errors.
            document.Validate(ValidationEventHandler);

            // Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99";

            // Validate only the first book element. The last book
            // element is invalid, but not included in validation.
            XmlNode bookNode = document.SelectSingleNode(@"/bk:bookstore/bk:book", manager);
            document.Validate(ValidationEventHandler, bookNode);
        }
        catch (XmlException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlException: {ex.Message}");
        }
        catch(XmlSchemaValidationException ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.XmlSchemaValidationException: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"XmlDocumentValidationExample.Exception: {ex.Message}");
        }
    }

    static void ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.Write("\nWARNING: ");
        else if (args.Severity == XmlSeverityType.Error)
            Console.Write("\nERROR: ");

        Console.WriteLine(args.Message);
    }
}
Imports System.Xml
Imports System.Xml.Schema

Class XmlDocumentValidationExample

    Shared Sub Main()

        Try

            ' Create a new XmlDocument instance and load
            ' the XML document into the DOM.
            Dim document As XmlDocument = New XmlDocument()
            document.Load("contosoBooks.xml")

            ' Add the XML schema for the XML document to the
            ' Schemas property of the XmlDocument.
            document.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")

            ' Validate the XML document loaded into the DOM.
            document.Validate(AddressOf ValidationEventHandler)

            ' Make an invalid change to the first and last 
            ' price elements in the XML document, and write
            ' the XmlSchemaInfo values assigned to the price
            ' element during validation to the console.
            Dim manager As XmlNamespaceManager = New XmlNamespaceManager(document.NameTable)
            manager.AddNamespace("bk", "http://www.contoso.com/books")

            Dim priceNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book/bk:price", manager)

            Console.WriteLine("SchemaInfo.IsDefault: {0}", priceNode.SchemaInfo.IsDefault)
            Console.WriteLine("SchemaInfo.IsNil: {0}", priceNode.SchemaInfo.IsNil)
            Console.WriteLine("SchemaInfo.SchemaElement: {0}", priceNode.SchemaInfo.SchemaElement)
            Console.WriteLine("SchemaInfo.SchemaType: {0}", priceNode.SchemaInfo.SchemaType)
            Console.WriteLine("SchemaInfo.Validity: {0}", priceNode.SchemaInfo.Validity)

            priceNode.InnerXml = "A"

            Dim priceNodes As XmlNodeList = document.SelectNodes("/bk:bookstore/bk:book/bk:price", manager)
            Dim lastprice As XmlNode = priceNodes(priceNodes.Count - 1)

            lastprice.InnerXml = "B"

            ' Validate the XML document with the invalid changes.
            ' The invalid changes cause schema validation errors.
            document.Validate(AddressOf ValidationEventHandler)

            ' Correct the invalid change to the first price element.
            priceNode.InnerXml = "8.99"

            ' Validate only the first book element. The last book
            ' element is invalid, but not included in validation.
            Dim bookNode As XmlNode = document.SelectSingleNode("/bk:bookstore/bk:book", manager)
            document.Validate(AddressOf ValidationEventHandler, bookNode)

        Catch ex As XmlException
            Console.WriteLine("XmlDocumentValidationExample.XmlException: {0}", ex.Message)

        Catch ex As XmlSchemaValidationException
            Console.WriteLine("XmlDocumentValidationExample.XmlSchemaValidationException: {0}", ex.Message)

        Catch ex As Exception
            Console.WriteLine("XmlDocumentValidationExample.Exception: {0}", ex.Message)

        End Try

    End Sub

    Shared Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)

        If args.Severity = XmlSeverityType.Warning Then
            Console.Write(vbCrLf & "WARNING: ")
        Else
            If args.Severity = XmlSeverityType.Error Then
                Console.Write(vbCrLf & "ERROR: ")
            End If
        End If
        Console.WriteLine(args.Message)

    End Sub

End Class

Exemplet tar som indata de contosoBooks.xml och contosoBooks.xsd filer som refereras till i "Validera ett XML-dokument när det läses in i DOM" ovan.

Hantera valideringsfel och varningar

Verifieringsfel för XML-schema rapporteras när XML-data som läses in i DOM verifieras. Du får ett meddelande om alla schemavalideringsfel som hittas när XML-data verifieras när de läses in, eller när du verifierar ett tidigare ovaliderat XML-dokument.

Valideringsfel hanteras av ValidationEventHandler. Om en ValidationEventHandler har tilldelats till XmlReaderSettings-instansen eller skickats till Validate-metoden för klassen XmlDocument hanterar ValidationEventHandler schemavalideringsfel. annars utlöses en XmlSchemaValidationException när ett schemavalideringsfel påträffas.

Anmärkning

XML-data läses in i DOM trots schemavalideringsfel om inte din ValidationEventHandler skapar ett undantag för att stoppa processen.

Schemavalideringsvarningar rapporteras inte om inte flaggan ReportValidationWarnings har angetts till XmlReaderSettings-objektet.

Exempel som illustrerar ValidationEventHandlerfinns i "Validera ett XML-dokument när det läses in i DOM" och "Validera ett XML-dokument i DOM" ovan.

Se även