Why is XML Deserilzation not throwing exceptions when it should
Here is some dummy xml and dummy xml schema I made.
schema
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.domain.com"
xmlns="http://www.domain.com"
elementFormDefault="qualified">
<xs:element name="vehicles">
<xs:complexType>
<xs:sequence>
<xs:element name="owner" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="2" />
<xs:maxLength value="8" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Car" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Information" type="CarInfo" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Truck">
<xs:complexType>
<xs:sequence>
<xs:element name="Information" type="CarInfo" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SUV">
<xs:complexType>
<xs:sequence>
<xs:element name="Information" type="CarInfo" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="CarInfo">
<xs:sequence>
<xs:element name="CarName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CarPassword">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="6"/>
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CarEmail">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
xml sample
<?xml version="1.0" encoding="utf-8" ?>
<vehicles>
<owner>Car</owner>
<Car>
<Information>
<CarName>Bob</CarName>
<CarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
<Information>
<CarName>Bob2</CarName>
<CarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
</Car>
<Truck>
<Information>
<CarName>Jim</CarName>
<CarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
<Information>
<CarName>Jim2</CarName>
<C开发者_如何学JAVAarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
</Truck>
<SUV>
<Information>
<CarName>Jane</CarName>
<CarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
<Information>
<CarName>Jane</CarName>
<CarPassword>123456</CarPassword>
<CarEmail>Red@test.com</CarEmail>
</Information>
</SUV>
</vehicles>
Serialization Class
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
[XmlRoot("vehicles")]
public class MyClass
{
public MyClass()
{
Cars = new List<Information>();
Trucks = new List<Information>();
SUVs = new List<Information>();
}
[XmlElement(ElementName = "owner")]
public string Owner { get; set; }
[XmlElement("Car")]
public List<Information> Cars { get; set; }
[XmlElement("Truck")]
public List<Information> Trucks { get; set; }
[XmlElement("SUV")]
public List<Information> SUVs { get; set; }
}
public class CarInfo
{
public CarInfo()
{
Info = new List<Information>();
}
[XmlElement("Information")]
public List<Information> Info { get; set; }
}
public class Information
{
[XmlElement(ElementName = "CarName")]
public string CarName { get; set; }
[XmlElement("CarPassword")]
public string CarPassword { get; set; }
[XmlElement("CarEmail")]
public string CarEmail { get; set; }
}
Now I think this should all validate. If not assume it is write as my real file does work and this is what this dummy one is based off. Now my problem is this. I want to enforce as much as I can from my schema. Such as the "owner" tag must be the first element and should show up one time and only one time ( minOccurs="1" maxOccurs="1").
Right now I can remove the owner element from my dummy xml file and deseriliaze it and it will go on it's happy way and convert it to object and will just put that property as null. I don't want that I want it to throw an exception or something saying this does match what was expected.
I don't want to have to validate things like that once deserialized. Same goes for the <car></car>
tag I want that to appear always even if there is no information yet I can remove that too and it will be happy with that.
So what tags do I have to add to make my serialization class know that these things are required and if they are not found throw an exception.
What API is doing the [de]serialization? If this is something inbuilt like asmx, then there probably isn't much you can do (short of implementing IXmlSerializable
, which is horrible), but if you have direct control over the XmlReader
/ XmlWriter
creation (for example, from a file or network socket) you can get the reader/writer to do the validation for you, like so.
I dont know about elements, but you can definately make an attribute "owner" and make it required, that works. And you can use [XmlAttribute] on owner property.
精彩评论