1

I have classes generated from an xsd schema with xsd.exe. I don't have control over the schema. Reading, writing with XmlSerlializer and validation of the serialized data works just fine. I'd like to implement on-line error checking for my data what includes user input, based on the rules in the schema. Again I have no problem serializing and validating against, but then I see no easy way of tracking back the location of the fault, in which instance of which class did it occur. I found a comment mentioning that the reason for no XmlValidatingWriter exist is that the classes should already ensure schema compatibility, however this is not true for the xsd.exe generated classes. (structure and types are good but unique fields, patter matches etc. are not covered) There is a page about XmlSchemaValidator push-based validation but this seems super manual to me totally ignoring the fact that all of my classes are xml serializable.

I found similar questions but nobody seems to have this particular goal, nor I could find an answer that would lead me to a solution. I'm ok concluding this is not possible for some reason -as it looks to me now- but I'd like to understand the reason and get to know where my whole architecture went wrong.

Thank you.

  • Most `XmlReader` instances implement [`IXmlLineInfo`](https://msdn.microsoft.com/en-us/library/system.xml.ixmllineinfo.aspx). `XElement` [implements this also](https://stackoverflow.com/a/4471030/3744182). Depending upon how you validate your XML you may be able to use this to extract the fault location along the lines of [this answer](https://stackoverflow.com/a/29882953/3744182) or [this one](https://stackoverflow.com/a/621069/3744182). Can you [edit] your question to share a [mcve] showing how you validate your XML? – dbc Aug 26 '17 at 18:04
  • Also, `XmlSchemaException` has line and position information. It's right there in [`XmlReaderSettings.ValidationEventHandler`](https://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.validationeventhandler(v=vs.110).aspx) so you should be good to go. – dbc Aug 26 '17 at 18:20
  • See also [Can I fail to deserialize with XmlSerializer in C# if an element is not found?](https://stackoverflow.com/a/259969/3744182) for a generic method to validate during deserialization. Validation failures will be passed a [`ValidationEventArgs`](https://msdn.microsoft.com/en-us/library/system.xml.schema.validationeventargs(v=vs.110).aspx) containing an `XmlSchemaException`. – dbc Aug 26 '17 at 18:42
  • @dbc, thanks. I can do this, but I'm not really interested in where the fault is in the serialized data (line/position). I care about where it is in my object hierarchy before serialization. I'm wondering if there's a way of getting LineInfo during serialization what tells me when XmlWriter writes one of my objects into the stream in which line it ended up. This way at least I could track back the exact object based on the line in the XmlSchemaException or in the event handler. – Marsupilami Aug 26 '17 at 19:03
  • Btw I'm using XDocument.Validate after serlializing into it. But I don't think that matters. – Marsupilami Aug 26 '17 at 19:11

1 Answers1

1

Ok, here is what I ended up doing. I'm not proud of it.

  1. I have a base class that all of my xml nodes inherit from. I added a GUID property to it that is marked to be an xmlattribute and has the xmlignore attribute by default so that it doesn't take part in normal serialization / deserialization.
  2. When I'm about to serialize for validation I create an xmlattributesoverride to get rid of the xmlignore of the GUID property. The guid is going to be serialized to an xml attribute of each element.
  3. I create a new XDocument and serialize into it.
  4. I run XDocument.Validate using the schema I need to validate against.
  5. In the validation event handler I ignore all the errors that complain about the extra guid attribute.
  6. When I get a real validation error or warning I can find the actual object that got serialized into that particular element based on the guid.
  7. Profit.

Probably highly inefficient but for the size of the data I'm working with it's ok.