为什么这个XML应该验证,什么时候不应该?

时间:2015-07-31 17:11:13

标签: c# xml validation

我有以下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" );

2 个答案:

答案 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不匹配。