【发布时间】:2014-02-10 17:25:06
【问题描述】:
我正在尝试使用架构验证 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(){}) 而不是反序列化来查看是否引发了验证错误,但我没有遇到任何问题。
【问题讨论】:
-
您在哪里指定要使用的架构?
-
另外,如果您在架构中指定 targetNamespace,XML 中的元素不应该在该命名空间内吗?
-
要使用的架构在设置部分给出。我正在添加一个“mySchemaSet”,我正在向其中添加架构。我只是在这里省略了它,因为我不想弄乱这个问题。至于命名空间,由于我没有为我的 xml 元素指定 xmlns:target 前缀,它们将恢复为使用默认 xmlns w3.org/2001/XMLSchema"
-
但是您在 XSD 文档中指定了目标命名空间
http://customUri。因此,XML 中默认命名空间中的Message元素不是 XSD 的http://customUri命名空间中的Message元素。 -
仅供参考,您在
XSD中缺少http://customUri:Messages(复数)的元素声明。
标签: c# xml validation xsd xmlreader