質問

I'm trying to validate an xml string with a schema and am running into an issue where it's not recognizing restrictions in the xsd using facets. I've created a unit test where I'm serializing an object into an xml, validating the xml using my schema and deserializing the xml back to the object. Everything works great, but for some reason I'm not getting an error when my latitude is within the range specified in the schema. I've defined a latitude to be within -90 to 90 however I'm not getting an error when I'm exceeding the bound. Here's the xml I get after serializing:

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

The schema that I'm using is shown below. The relevant part with the latitude is in the middle. (I know it's a bit ugly and I'm trying to get them to optimize their schema generation code)

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

My settings for reading the xml are: (notice I'm specifying flags for ReportValidationWarnings and ProcessIdentityContraints as well as using a validation handler to detect warnings)

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

The code I'm using to deserialize is pretty standard.

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

I also tried doing a while(reader.read(){}) instead of deserializing to see if a validation error is thrown but I'm not getting any issue.

役に立ちましたか?

解決

Try your code with the following 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>

As Vadim says in the comments, you need to tell the validator that the types in your XML are those defined in the schema. And the way to do that is to include the target namespace of the schema in your XML instance.

Without this, all the validator can do is check if the XML is well formed. This is why it is returning a valid result.

UPDATE

enter image description here

enter image description here

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top