【问题标题】:Why does this XML validate, when it shouldn't?为什么这个 XML 在不应该验证的时候验证?
【发布时间】:2015-07-31 17:11:13
【问题描述】:

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

读取.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" );

【问题讨论】:

  • 不太清楚“标签周围缺少标签会”是什么意思。您提供的 xml sn-p 对我来说看起来很正常。
  • 查看其他相关问题...stackoverflow.com/questions/15741469/… ...您可能需要添加命名空间来触发验证? .... ...自从我不得不进行 XML 验证以来已经有一段时间了,但我认为通过 XmlSchemaSet 添加它是不够的。
  • @AndresCastor:对不起,我编辑了这个问题。我在正文中包含了小于和大于一些标签名称,它们被网站的软件吞噬了。
  • @overslacked:向 XML 添加 XML 命名空间是无关紧要的。就其本身而言,该 XML 不应该在不生成一些错误的情况下通过验证代码,但确实如此。我错过了什么?
  • @overslacked:原来我对您的评论的评论是错误的,尽管我不清楚为什么它是错误的。我很抱歉。

标签: c# xml validation


【解决方案1】:

因为你已经定义了

<xs:element name="read" type="read"/>

read 元素是您的 XML 的有效根元素。作为&lt;xs:schema&gt; 的直接子元素的每个元素都有资格成为根元素(即使是包含架构中的元素)。

【讨论】:

  • 好的,我会买那个(我对 XSD 的工作原理不是很了解)。如何修复它以使读取标签不再是有效的根元素?
  • 我认为您可以删除此行。 ReadFile.xsd 指的是 type read,而不是 element read
  • 你的意思是Read.xsd文件中的那一行吗?
  • 是的,我就是这个意思。
  • 在进行更改和一些实验之后,我发现如果我在read 标记上指定命名空间,XML 不会验证,如&lt; read xmlns:"elsag:lprcore"&gt;&lt; /read&gt;。这是我所期望的。但是,如果我不包含命名空间,XML 会验证。我不明白为什么会这样。它在 VS 中也以这种方式工作。我是否需要指定一些东西来要求在 XML 中存在命名空间?
【解决方案2】:

感谢 Glorfindel 在答案中发布的信息和 overslacked 发布的链接,我已经能够让我的程序中的 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 文件视为无效。与 XSD 不匹配的任何其他 XML 部分也会被标记。

【讨论】:

    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多