Ich habe ein wirklich seltsames Problem, ein XML-Dokument gegen eine gültige XSD mit C# XDocument.Validate oder XMLReaderSettings mit erforderlichen Konfigurationen zu validieren. Das Problem ist: Wenn im XML-Dokument Fehler auftreten, kann der Validierungsprozess unter bestimmten Bedingungen nicht alle Fehler erfassen, und ich kann kein Muster für diese Anomalität finden.XDocument.Validate nicht alle Fehler gegen XSD
Hier ist meine XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
\t \t \t targetNamespace="http://www.somesite.com/somefolder/messages"
\t \t \t xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="Header">
<xs:complexType>
<xs:sequence>
<xs:element name="MessageId" type="xs:string" />
<xs:element name="MessageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Body">
<xs:complexType>
<xs:sequence>
<xs:element name="Abc001">
<xs:complexType>
<xs:sequence>
<xs:element name="Abc002" type="xs:string" />
<xs:element name="Abc003" type="xs:string" minOccurs="0" />
<!--<xs:element name="Abc004" type="xs:string" />-->
<xs:element name="Abc004">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="200"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Abc005">
<xs:complexType>
<xs:sequence>
<xs:element name="Abc006" type="xs:unsignedShort" />
<xs:element name="Abc007">
<xs:complexType>
<xs:sequence>
<xs:element name="Abc008" type="xs:string"/>
<xs:element name="Abc009" type="xs:string" minOccurs="0"/>
<xs:element name="Abc010" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Abc011" type="xs:date" />
<xs:element name="Abc012">
<xs:complexType>
<xs:sequence>
<xs:element name="Abc013" type="xs:string" />
<xs:element name="Abc014" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Und hier ist das XML-Dokument gegen diese XSD validiert:
<?xml version="1.0" encoding="utf-8"?>
<Message xmlns="http://www.somesite.com/somefolder/messages">
\t <Header>
\t \t <MessageId>Lorem</MessageId>
\t \t <MessageSource>Ipsum</MessageSource>
\t </Header>
\t <Body>
\t \t <Abc001>
\t \t \t <Abc002>dolor</Abc002>
\t \t \t <Abc003>sit amet</Abc003>
\t \t \t <Abc004>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</Abc004>
\t \t \t <Abc005>
\t \t \t \t <Abc006>1234</Abc006>
\t \t \t \t <Abc007>
\t \t \t \t \t <Abc008>Ut enim</Abc008>
\t \t \t \t \t <Abc009>ad</Abc009>
\t \t \t \t \t <Abc010>minim</Abc010>
\t \t \t \t </Abc007>
\t \t \t \t <Abc011>1982-10-17</Abc011>
\t \t \t \t <Abc012>
\t \t \t \t \t <Abc013>veniam</Abc013>
\t \t \t \t \t <Abc014>nostrud</Abc014>
\t \t \t \t </Abc012>
\t \t \t </Abc005>
\t \t </Abc001>
\t </Body>
</Message>
<?xml version="1.0" encoding="utf-8"?>
<Message xmlns="http://www.somesite.com/somefolder/messages">
\t <Header>
\t \t <MessageId>Lorem</MessageId>
\t \t <MessageSource>Ipsum</MessageSource>
\t </Header>
\t <Body>
\t \t <Abc001>
\t \t \t <Abc002>dolor</Abc002>
\t \t \t <Abc003>sit amet</Abc003>
\t \t \t
\t \t \t <!--The value for Abc004 is increased beyond the allowed 200 characters-->
\t \t \t
\t \t \t <Abc004>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</Abc004>
\t \t \t <Abc005>
\t \t \t \t <Abc006>1234</Abc006>
\t \t \t \t <Abc007>
\t \t \t \t \t <Abc008>Ut enim</Abc008>
\t \t \t \t \t <ABC009>AD</ABC009>
\t \t \t \t \t
\t \t \t \t \t <!--<Abc010>minim</Abc010> Required element removed-->
\t \t \t \t </Abc007>
\t \t \t \t
\t \t \t \t <!--Date formate below is wrong-->
\t \t \t \t <Abc011>1982-10-37</Abc011>
\t \t \t \t
\t \t \t \t <Abc012>
\t \t \t \t \t <Abc013>veniam</Abc013>
\t \t \t \t \t <Abc014>nostrud</Abc014>
\t \t \t \t </Abc012>
\t \t \t </Abc005>
\t \t \t <!--the element below is not allowed-->
\t \t \t <Abc15>Not allowed</Abc15>
\t \t </Abc001>
\t </Body>
</Message>
und hier ist meine resultierende xml, das zeigt alle Fehler:
<MessageResponse xmlns="http://www.somesite.com/somefolder/messages">
<Result>false</Result>
<Status>Failed</Status>
<FaultCount>4</FaultCount>
<Faults>
<Fault>
<FaultCode>ERR01</FaultCode>
<FaultMessage>The 'http://www.somesite.com/somefolder/messages:Abc004' element is invalid - The value 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' is invalid according to its datatype 'String' - The actual length is greater than the MaxLength value.</FaultMessage>
</Fault>
<Fault>
<FaultCode>ERR02</FaultCode>
<FaultMessage>The element 'Abc007' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'ABC009' in namespace 'http://www.somesite.com/somefolder/messages'. List of possible elements expected: 'Abc009, Abc010' in namespace 'http://www.somesite.com/somefolder/messages'.</FaultMessage>
</Fault>
<Fault>
<FaultCode>ERR03</FaultCode>
<FaultMessage>The 'http://www.somesite.com/somefolder/messages:Abc011' element is invalid - The value '1982-10-37' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:date' - The string '1982-10-37' is not a valid Date value.</FaultMessage>
</Fault>
<Fault>
<FaultCode>ERR04</FaultCode>
<FaultMessage>The element 'Abc001' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'Abc15' in namespace 'http://www.somesite.com/somefolder/messages'.</FaultMessage>
</Fault>
</Faults>
</MessageResponse>
Hier ist der seltsame Teil. Wenn ich einen weiteren Fehler am Anfang des Elements "Abc001" einfüge und auch alle anderen vorhandenen Fehler behalte, ist das Ergebnis völlig durcheinander. Hier ist der XML mit dem neu eingeführten Fehler:
<?xml version="1.0" encoding="utf-8"?>
<Message xmlns="http://www.somesite.com/somefolder/messages">
\t <Header>
\t \t <MessageId>Lorem</MessageId>
\t \t <MessageSource>Ipsum</MessageSource>
\t </Header>
\t <Body>
\t \t <Abc001>
\t \t \t <!--newly introduced error - removed the following element-->
\t \t \t <!--<Abc002>dolor</Abc002>-->
\t \t \t <Abc003>sit amet</Abc003>
\t \t \t <!--The value for Abc004 is increased beyond the allowed 200 characters-->
\t \t \t <Abc004>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</Abc004>
\t \t \t <Abc005>
\t \t \t \t <Abc006>1234</Abc006>
\t \t \t \t <Abc007>
\t \t \t \t \t <Abc008>Ut enim</Abc008>
\t \t \t \t \t <ABC009>AD</ABC009>
\t \t \t \t \t <!--<Abc010>minim</Abc010>-->
\t \t \t \t </Abc007>
\t \t \t \t <Abc011>1982-10-37</Abc011>
\t \t \t \t <Abc012>
\t \t \t \t \t <Abc013>veniam</Abc013>
\t \t \t \t \t <Abc014>nostrud</Abc014>
\t \t \t \t </Abc012>
\t \t \t </Abc005>
\t \t \t <!--the element below is not allowed-->
\t \t \t <Abc15>Not allowed</Abc15>
\t \t </Abc001>
\t </Body>
</Message>
und schließlich, hier ist das Überprüfungsergebnis:
<MessageResponse xmlns="http://www.somesite.com/somefolder/messages">
<Result>false</Result>
<Status>Failed</Status>
<FaultCount>1</FaultCount>
<Faults>
<Fault>
<FaultCode>ERR01</FaultCode>
<FaultMessage>The element 'Abc001' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'Abc003' in namespace 'http://www.somesite.com/somefolder/messages'. List of possible elements expected: 'Abc002' in namespace 'http://www.somesite.com/somefolder/messages'.</FaultMessage>
</Fault>
</Faults>
</MessageResponse>
Hier ist mein C# -Code Ich verwende zur Validierung:
public async Task<IMIDPreValidationAckMessage> ValidateXmlMessage(XDocument doc)
{
var result = new PreValidationAckMessage();
result.Result = true;
result.Status = "Succeeded";
var xsd = HttpContext.Current.Server.MapPath("~/message01.xsd");
try
{
var uri = new System.Uri(xsd);
var localPath = uri.LocalPath;
var docNameSpace = doc.Root.Name.Namespace.NamespaceName;
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(docNameSpace, localPath);
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.ValidationType = ValidationType.Schema;
xrs.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
xrs.Schemas = schemas;
result.XSDNamespace = doc.Root.GetDefaultNamespace().NamespaceName;
var errCode = 1;
xrs.ValidationEventHandler += (s, e) =>
{
var msg = e.Message;
result.Result = false;
result.Status = "Failed";
result.FaultCount++;
result.Faults.Add(new Fault
{
FaultCode = "ERR" + errCode++.ToString().PadLeft(2, '0'),
FaultMessage = e.Message
});
};
using (XmlReader xr = XmlReader.Create(doc.CreateReader(), xrs))
{
while (xr.Read()) { }
}
}
catch (System.Exception ex)
{
result.Result = false;
result.Status = "Unknown Error";
}
return result;
}
Kann mir bitte jemand sagen, was hier nicht stimmt?
Wäre gut, alle Klassen in Ihrem letzten Snippet aufzunehmen, nur damit Sie es kopieren und einfügen und ausführen können. – Evk
@Evk: Danke für eine schnelle Antwort. Der Code, den ich nicht gepostet habe, sind verschachtelte Klassen und auch hier sind sie wirklich irrelevant. Wenn Sie die Fehlermeldungen nur einer Liste von Strings innerhalb des validationeventhandlers hinzufügen, sollte dies für den Test ausreichen. Mein Code erfasst nur die Fehlermeldungen und erstellt daraus ein weiteres XML-Dokument. Das ist alles. –