为什么这个XML要验证,而它不应该验证
本文关键字:验证 不应该 XML 为什么 | 更新日期: 2023-09-27 18:05:43
我有以下XSD文件:
ReadFile.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="elsag:lprcore" elementFormDefault="qualified" targetNamespace="elsag:lprcore" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="Read.xsd" />
<xs:element name="reads" type="ReadFile" />
<xs:complexType name="ReadFile">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="read" nillable="true" type="read">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Read.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="elsag:lprcore" elementFormDefault="qualified" targetNamespace="elsag:lprcore" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="Snapshot.xsd"/>
<xs:include schemaLocation="GPS.xsd"/>
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:element name="read" type="read"/>
<xs:complexType name="read">
<xs:complexContent mixed="false">
<xs:extension base="snapshot">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="timestamp" type="xs:dateTime" />
<xs:element minOccurs="1" maxOccurs="1" name="plate" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="state" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="confidence" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1" name="overviews">
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="snapshot" type="snapshot"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="1" name="gps" type="gps" />
</xs:sequence>
<xs:attribute name="id" type="guid" use="required" />
<xs:attribute name="camera" type="xs:string" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
请注意,还有更多的文件组成了XSD,但我不相信他们是相关的问题,所以我没有包括他们。
我使用以下代码验证正在处理的XML文件。我想拒绝任何没有验证错误的文件:
StringBuilder validationErrors = new StringBuilder();
inDoc.Validate( schemas, ( o, e ) => {
validationErrors.AppendLine( e.Message );
} );
if ( !string.IsNullOrWhiteSpace( validationErrors.ToString() ) ) {
. . .
}
我将下面的XML文件传递给上面的代码,代码没有为它生成任何验证错误消息。
<read>
<timestamp>2015-07-17T16:20:18.1540000-04:00</timestamp>
<plate>FED456</plate>
</read>
我本以为缺少read
标记周围的reads
标记会导致XML验证失败。问题是在验证代码中,还是在XSD中,或者这是正常的?
编辑:
下面是初始化schemas
变量的代码:
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add( "elsag:lprcore", @"XML'ReadFile.xsd" );
因为您已经定义了
<xs:element name="read" type="read"/>
read
元素是XML的有效根元素。每个<xs:schema>
的直接子元素都有资格成为根元素(即使是在包含的模式中)。
感谢gloria findel在回答中发布的信息和overlack发布的链接,我已经能够在我的程序中获得XML验证。
问题是程序不会将不包含命名空间的XML文件标记为无效。原因是XDocument.Validate
扩展方法创建了一个XmlReader
对象,其XmlReaderSettings
属性不包含ReportValidationWarnings
标志。因此,传递给该方法的ValidationEventHandler
委托不会为这些文件调用。
为了使验证逻辑工作,我定义了一个新的扩展方法,它包含了标志:
internal static class XmlValidationExtension {
public static void ValidateWithWarnings( this XDocument doc, XmlSchemaSet schemas, ValidationEventHandler validationCallback ) {
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add( schemas );
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler( validationCallback );
XmlReader reader = XmlReader.Create( doc.CreateReader(), settings );
while ( reader.Read() ) ;
}
}
这基本上与overlack所链接的问题的代码完全相同,但是XmlReader
是通过调用XDocment
对象的CreateReader
方法创建的。
这段代码现在认为任何没有使用正确名称空间的XML文件都是无效的。XML中与XSD不匹配的任何其他部分也会被标记。