Почему XML-десерилизация не вызывает исключений, когда должна - PullRequest
1 голос
/ 04 мая 2010

Вот несколько фиктивных XML и фиктивных XML схем, которые я сделал.

схема

<?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>
      <CarPassword>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>

Класс сериализации

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; }
}

Теперь я думаю, что все это должно подтвердить. Если не предположить, что это запись, так как мой настоящий файл работает, и это то, на чем основан этот фиктивный файл. Теперь моя проблема заключается в следующем. Я хочу использовать как можно больше из моей схемы. Например, тег "owner" должен быть первым элементом и должен отображаться один раз и только один раз (minOccurs = "1" maxOccurs = "1").

Прямо сейчас я могу удалить элемент owner из моего фиктивного xml-файла и десерилизовать его, и он пойдет по-своему, преобразовать его в объект и просто присвоит этому свойству значение null. Я не хочу, чтобы я выдавал исключение или что-то, говорящее, что это соответствует ожидаемому.

Я не хочу проверять подобные вещи после десериализации. То же самое касается тега <car></car>. Я хочу, чтобы он появлялся всегда, даже если информации пока нет, я тоже могу удалить его, и он будет рад этому.

Итак, какие теги я должен добавить, чтобы мой класс сериализации знал, что эти вещи необходимы, и если они не найдены, выдается исключение.

Ответы [ 2 ]

1 голос
/ 04 мая 2010

Какой API выполняет сериализацию [de]? Если это что-то встроенное, например asmx, то, вероятно, вы ничего не сможете сделать (за исключением реализации IXmlSerializable, что ужасно), но если вы имеете прямой контроль над созданием XmlReader / XmlWriter (например из файлового или сетевого сокета) вы можете заставить читателя / писателя выполнить проверку за вас, примерно так .

0 голосов
/ 04 мая 2010

Я не знаю об элементах, но вы можете сделать атрибут «владелец» и сделать его обязательным, это работает. И вы можете использовать [XmlAttribute] в свойстве владельца.

...