Как выполнить проверку с помощью XSD (LINQ to XML)
Обновлен: November 2007
Пространство имен System.Xml.Schema содержит методы расширения, облегчающие проверку правильности XML-дерева по XSD-файлу. Дополнительные сведения см. в документации метода Validate.
Пример
В следующем примере создается набор схем XmlSchemaSet, затем с его помощью проводится проверка правильности двух объектов XDocument. Правильность одного документа подтверждается, а второго — нет.
string xsdMarkup =
@"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:element name='Root'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='Child1' minOccurs='1' maxOccurs='1'/>
<xsd:element name='Child2' minOccurs='1' maxOccurs='1'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>";
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", XmlReader.Create(new StringReader(xsdMarkup)));
XDocument doc1 = new XDocument(
new XElement("Root",
new XElement("Child1", "content1"),
new XElement("Child2", "content1")
)
);
XDocument doc2 = new XDocument(
new XElement("Root",
new XElement("Child1", "content1"),
new XElement("Child3", "content1")
)
);
Console.WriteLine("Validating doc1");
bool errors = false;
doc1.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("doc1 {0}", errors ? "did not validate" : "validated");
Console.WriteLine();
Console.WriteLine("Validating doc2");
errors = false;
doc2.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("doc2 {0}", errors ? "did not validate" : "validated");
Dim errors As Boolean = False
Private Sub XSDErrors(ByVal o As Object, ByVal e As ValidationEventArgs)
Console.WriteLine("{0}", e.Message)
errors = True
End Sub
Sub Main()
Dim xsdMarkup As XElement = _
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:element name='Root'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='Child1' minOccurs='1' maxOccurs='1'/>
<xsd:element name='Child2' minOccurs='1' maxOccurs='1'/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Dim schemas As XmlSchemaSet = New XmlSchemaSet()
schemas.Add("", xsdMarkup.CreateReader)
Dim doc1 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child2>content1</Child2>
</Root>
Dim doc2 As XDocument = _
<?xml version='1.0'?>
<Root>
<Child1>content1</Child1>
<Child3>content1</Child3>
</Root>
Console.WriteLine("Validating doc1")
errors = False
doc1.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("doc1 {0}", IIf(errors = True, "did not validate", "validated"))
Console.WriteLine()
Console.WriteLine("Validating doc2")
errors = False
doc2.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("doc2 {0}", IIf(errors = True, "did not validate", "validated"))
End Sub
В этом примере формируются следующие данные:
Validating doc1
doc1 validated
Validating doc2
The element 'Root' has invalid child element 'Child3'. List of possible elements expected: 'Child2'.
doc2 did not validate
В следующем примере подтверждается, что XML-документ из Образец XML-файла: заказчики и заказы (LINQ to XML) является правильным согласно схеме из Образец XSD-файла: заказчики и заказы. Затем в исходный XML-документ вносятся изменения. Изменяется атрибут CustomerID первого клиента. После этого изменения заказы ссылаются на несуществующего клиента, поэтому XML-документ больше не должен пройти проверку правильности.
В этом примере используется следующий XML-документ: Образец XML-файла: заказчики и заказы (LINQ to XML).
В этом примере используется следующая XSD-схема: Образец XSD-файла: заказчики и заказы.
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", "CustomersOrders.xsd");
Console.WriteLine("Attempting to validate");
XDocument custOrdDoc = XDocument.Load("CustomersOrders.xml");
bool errors = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");
Console.WriteLine();
// Modify the source document so that it will not validate.
custOrdDoc.Root.Element("Orders").Element("Order").Element("CustomerID").Value = "AAAAA";
Console.WriteLine("Attempting to validate after modification");
errors = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");
Dim errors As Boolean = False
Private Sub XSDErrors(ByVal o As Object, ByVal e As ValidationEventArgs)
Console.WriteLine("{0}", e.Message)
errors = True
End Sub
Sub Main()
Dim schemas As XmlSchemaSet = New XmlSchemaSet()
schemas.Add("", "CustomersOrders.xsd")
Console.WriteLine("Attempting to validate")
Dim custOrdDoc As XDocument = XDocument.Load("CustomersOrders.xml")
errors = False
custOrdDoc.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("custOrdDoc {0}", IIf(errors, "did not validate", "validated"))
Console.WriteLine()
' Modify the source document so that it will not validate.
custOrdDoc.<Root>.<Orders>.<Order>.<CustomerID>(0).Value = "AAAAA"
Console.WriteLine("Attempting to validate after modification")
errors = False
custOrdDoc.Validate(schemas, AddressOf XSDErrors)
Console.WriteLine("custOrdDoc {0}", IIf(errors, "did not validate", "validated"))
End Sub
В этом примере формируются следующие данные:
Attempting to validate
custOrdDoc validated
Attempting to validate after modification
The key sequence 'AAAAA' in Keyref fails to refer to some key.
custOrdDoc did not validate