2014-01-21 1 views
1

Я пытаюсь проверить строку xml со схемой, и я столкнулся с проблемой, когда он не распознает ограничения в xsd, используя facets. Я создал модульный тест, где я сериализую объект в xml, проверяя xml с помощью моей схемы и десериализуя xml обратно в объект. Все работает отлично, но по какой-то причине я не получаю ошибку, когда моя широта находится в пределах, указанном в схеме. Я определил широту, чтобы быть в пределах от -90 до 90, но я не получаю сообщение об ошибке, когда я превышу границу. Вот xml, который я получаю после сериализации:Почему XmlReader не проверяет ограничение ограничений

<?xml version="1.0" encoding="utf-8"?> 
<Messages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Message>  
    <Blocks> 
     <Location> 
     <Latitude>110.5</Latitude> 
     <Longitude>11.5</Longitude> 
     <IsValid>true</IsValid> 
     <PrecisionKilometers>1</PrecisionKilometers> 
     </Location>  
    </Blocks> 
    </Message> 
</Messages> 

Схема, которую я использую, показана ниже. Соответствующая часть с широтой находится посередине. (Я знаю, что это немного некрасиво, и я стараюсь, чтобы получить их, чтобы оптимизировать их схемы генерации кода)

<?xml version="1.0" encoding="utf-16"?> 
<xs:schema xmlns:VL="http://customUri" elementFormDefault="qualified" targetNamespace="http://customUri" id="MessageList" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Messages"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element minOccurs="1" maxOccurs="unbounded" name="Message" nillable="true"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element minOccurs="1" maxOccurs="unbounded" name="Blocks"> 
       <xs:complexType> 
        <xs:all> 

        <xs:element minOccurs="0" maxOccurs="1" name="Location" nillable="true"> 
         <xs:complexType> 
         <xs:sequence> 
          <xs:element minOccurs="1" maxOccurs="1" name="Latitude"> 
          <xs:simpleType> 
           <xs:restriction base="xs:double"> 
           <xs:minInclusive value="-90" /> 
           <xs:maxExclusive value="90" /> 
           </xs:restriction> 
          </xs:simpleType> 
          </xs:element> 
          <xs:element minOccurs="1" maxOccurs="1" name="Longitude"> 
          <xs:simpleType> 
           <xs:restriction base="xs:double"> 
           <xs:minInclusive value="-180" /> 
           <xs:maxExclusive value="180" /> 
           </xs:restriction> 
          </xs:simpleType> 
          </xs:element> 
          <xs:element minOccurs="1" maxOccurs="1" name="IsValid" type="xs:boolean" /> 
          <xs:element minOccurs="0" maxOccurs="1" name="PrecisionKilometers" nillable="true" type="xs:double" /> 
         </xs:sequence> 
         </xs:complexType> 
        </xs:element> 

        </xs:all> 
       </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Мои настройки для чтения XML являются: (уведомление я указанием флагов ReportValidationWarnings и ProcessIdentityContraints, а также как с помощью обработчика проверки для обнаружения предупреждений)

var settings = new XmlReaderSettings 
      { 
      ValidationType = ValidationType.Schema, 
      ValidationFlags =   
       XmlSchemaValidationFlags.ReportValidationWarnings | 
       XmlSchemaValidationFlags.ProcessInlineSchema | 
       XmlSchemaValidationFlags.ProcessSchemaLocation | 
       XmlSchemaValidationFlags.ProcessIdentityConstraints | 
       XmlSchemaValidationFlags.AllowXmlAttributes, 
      IgnoreWhitespace = true, 
      IgnoreComments = true, 
      }; 
settings.ValidationEventHandler += (o, ex) => 
      {    
      if (ex.Severity == XmlSeverityType.Warning || ex.Severity == XmlSeverityType.Error) 
      { 
       //do something 
      } 
      }; 
    settings.Schemas.Add(mySchemaSet); 

код я использую для десериализации является довольно стандартным.

XmlReader reader = XmlReader.Create(memoryStreamContainingXml, settings); 
var serializer = new XmlSerializer(typeof(MessageList)); 
MessageList returned = ser.Deserialize(reader) as MessageList; 

Я также пытался делать while(reader.read(){}) вместо десериализации, чтобы увидеть, если брошена ошибка проверки, но я не получаю какой-либо вопрос.

+0

Где вы указать, какие схемы использовать? – Vadim

+1

Кроме того, если вы указываете targetNamespace в своей схеме, не должны ли элементы XML находиться внутри этого пространства имен? – Vadim

+0

Используемая схема указана в разделе настроек. Я добавляю «mySchemaSet», к которому я добавляю схему. Я просто опустил его здесь, так как я не хотел загромождать вопрос. Что касается пространства имен, поскольку я не указываю xmlns: целевой префикс для своих xml-элементов, они вернутся к использованию xmlns по умолчанию http://www.w3.org/2001/XMLSchema " – arviman

ответ

1

Попробуйте код следующим XML:

<ns0:Messages xmlns:ns0="http://customUri"> 
    <ns0:Message> 
    <ns0:Blocks> 
     <ns0:Location> 
     <ns0:Latitude>110.0</ns0:Latitude> 
     <ns0:Longitude>11.5</ns0:Longitude> 
     <ns0:IsValid>true</ns0:IsValid> 
     <ns0:PrecisionKilometers>1</ns0:PrecisionKilometers> 
     </ns0:Location> 
    </ns0:Blocks> 
    </ns0:Message> 
</ns0:Messages> 

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

Без этого все, что может сделать валидатор, это проверить, правильно ли сформирован XML. Вот почему он возвращает действительный результат.

UPDATE

enter image description here

enter image description here

+0

Нет, это не работает, когда я пытаюсь это сделать. Он выдает исключение {« не ожидалось."} – arviman

+0

К сожалению, извините корневой узел! Изменили, попробуйте еще раз. –

+0

Да, я попробовал это на схеме, сгенерированной на основе только сообщения. Я повторил это в MessageList, но получаю аналогичную ошибку. – arviman

Смежные вопросы