XDocument.Validate - Expected Data Error Element Type

I have a class that validates the provided XML document against the supplied XSD. In the class, I call the XDocument.Validate method to validate and get the following error:

http://www.example.com/enrollrequest1:requested-payment-date 'the item is invalid - the value "2015-05-28T00: 00: 00" is invalid according to its data type http://www.w3.org/ 2001 / XMLSchema: date '- The string' 2015-05-28T00: 00: 00 'is not a valid XsdDateTime value.

The value for the element was set from the .NET DateTime variable .NET DateTime , which ultimately sets it with the time part turned on, since .NET does not have the equivalent of xs: date type.

Values ​​for elements are set from a common module, so I cannot select and select elements and adjust their values. The developer sends me the value in the .NET DateTime type, which my program in turn calls the XElemet.SetValue(value) method to set it.

In addition, the XSD file is out of my control. Therefore, changing the XSD is not an option.

Is there a way to find out what the expected type of XElement that caused the error is? As soon as I know this, I can just come up with or customize my code accordingly. So, for example, in this case, if I know that the expected type is xs:date (and not xs:datetime ), I can just enter the value of the input.

Here is my validation class if this helps:

 Option Strict On Imports System.XML.Schema Public Class XmlSchemaValidator Public ReadOnly Errors As New List(Of String) Private XDoc As XDocument Private Schemas As XmlSchemaSet Public Sub New(ByVal doc As XDocument, ByVal schemaUri As String, ByVal targetNamespace As String) Me.XDoc = doc Me.Schemas = New XmlSchemaSet Me.Schemas.Add(targetNamespace, schemaUri) End Sub Public Sub Validate() Errors.Clear() XDoc.Validate(Schemas, AddressOf XsdErrors) End Sub Private Sub XsdErrors(ByVal sender As Object, ByVal e As ValidationEventArgs) Errors.Add (e.Message) End Sub End Class 

Here is the function that sets the xml node values.

 Function SetValue(ByVal xmlDoc As XDocument, ByVal keyValues As Dictionary(Of String, Object)) As Boolean '' set values For Each kvp In keyValues Dim xe As XElement = xmlDoc.Root.XPathSelectElement(kvp.Key) ''-- this is buggy implementation for handling xs:date vs xs:datetime that needs to be corrected... 'If TypeOf kvp.Value Is DateTime AndAlso DirectCast(kvp.Value, DateTime).TimeOfDay = TimeSpan.Zero Then ' xe.SetValue(DirectCast(kvp.Value, DateTime).ToString("yyyy-MM-dd")) 'Else xe.SetValue(kvp.Value) 'End If Next '' validate final document Dim schemaValidator As New XmlSchemaValidator(xmlDoc, schemaFile, "") schemaValidator.Validate() If schemaValidator.Errors.Count > 0 Then 'Error Logging code goes here... Return False End If Return True End Function 
+6
source share
1 answer

You wrote in an earlier comment:

"I want to know what the XSD expects for this item"

Then keep in mind that you can use the first “sender” parameter of your validation handlers, for example adapt this MSDN sample like, for example,

  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))); // (just for debug spying) var schemata = new XmlSchema[1]; schemas.CopyTo(schemata, 0); XDocument errorDoc = new XDocument( new XElement("Root", new XElement("Child1", "content1"), new XElement("Child2", "content2"), new XElement("Child2", "content3") // (must fail validation on maxOccurs) ) ); Console.WriteLine(); Console.WriteLine("Validating errorDoc"); errorDoc.Validate(schemas, (sender, args) => { Console.WriteLine("{0}", args.Message); // (what you're already doing) Console.WriteLine(); // but there also: var xElement = sender as XElement; if (xElement != null) { Console.WriteLine("Element {0} invalid : {1}", xElement, e.Exception.Message); } }); Console.ReadKey(); 

This can lead to the exit with sufficient information about the recognized criminals in the document, I hope:

 Validating errorDoc The element 'Root' has invalid child element 'Child2'. Element <Child2>content3</Child2> invalid : The element 'Root' has invalid child element 'Child2'. 

In any case, once you find out the culprit in an invalid document, you are more likely to more reliably match the corresponding definitions in the schemas (s) used for this check (rather than simply relying on the error string of the schema check).

(sorry for the answer in C # syntax, but I would prefer not to write in incorrect VB.NET, I'm already too rusty)

'Hope this helps.

0
source

Source: https://habr.com/ru/post/988147/


All Articles