我有以下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>
我原以为reads
标记周围缺少read
标记会导致XML验证失败。是验证码中的问题还是XSD中的问题还是正常的?
编辑:
以下是初始化schemas
变量的代码:
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add( "elsag:lprcore", @"XML\ReadFile.xsd" );
答案 0 :(得分:1)
因为你已经定义了
<xs:element name="read" type="read"/>
read
元素是XML的有效根元素。作为<xs:schema>
的直接子元素的每个元素都有资格成为根元素(即使是包含的模式中的元素)。
答案 1 :(得分:0)
感谢Glorfindel在回答中发布的信息以及过度发布的链接,我已经能够在我的程序中使用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() ) ;
}
}
这与the question linked to by overslacked中的确切代码完全相同,但是XmlReader
是通过调用XDocment
对象的CreateReader
方法创建的。
此代码现在认为任何不使用正确命名空间的XML文件都是无效的。 XML的任何其他部分都与XSD不匹配。