我正在尝试使用架构验证xml字符串,并且遇到了使用facets无法识别xsd中的限制的问题。我已经创建了一个单元测试,我将一个对象序列化为xml,使用我的模式验证xml并将xml反序列化回对象。一切都很好,但由于某些原因,当我的纬度在模式中指定的范围内时,我没有收到错误。我已经将纬度定义在-90到90之间但是当我超出界限时我没有收到错误。这是序列化后得到的xml:
<?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 :(得分: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>
正如Vadim在评论中所说,您需要告诉验证者XML中的类型是模式中定义的类型。这样做的方法是在XML实例中包含模式的目标名称空间。
如果没有这个,所有验证器都可以检查XML是否格式正确。这就是它返回有效结果的原因。
<强>更新强>