C# 使用 XmlReader.Create 针对 XSD 反序列化和验证 XML 文件无效

C# Deserializing, and validating an XML file against an XSD using XmlReader.Create isn't working

我正在使用 Visual Studio 2015。 对于命名不当的 "firstName" 元素,我深表歉意。它应该是 "fullName",但由于我已经为架构生成了 class,并且这只是为了我自己的学习,所以我将其保留原样。 我这里有一个 XML 模式:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="address-schema"
targetNamespace="http://tempuri.org/address-schema.xsd"
elementFormDefault="qualified"
attributeFormDefault="qualified"
xmlns:addr="http://tempuri.org/address-schema.xsd"
xmlns:mstns="http://tempuri.org/address-schema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:element name="address">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="firstName">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="first" type="addr:nameComponent"/>
              <xs:element name="middle" type="addr:nameComponent" minOccurs="0"/>
              <xs:element name="last" type="addr:nameComponent"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="nameComponent">
    <xs:simpleContent>
      <xs:extension base="xs:string"/>
    </xs:simpleContent>
  </xs:complexType>

</xs:schema>

还有一个我认为符合架构的 XML 文件:

<?xml version="1.0" encoding="utf-8" ?>
<addr:address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://tempuri.org/address-schema.xsd address-schema.xsd" 
          xmlns:addr="http://tempuri.org/address-schema.xsd">
  <addr:firstName>
    <addr:first>Some</addr:first>
    <addr:middle>Bodys</addr:middle>
    <addr:last>Name</addr:last>
  </addr:firstName>
</addr:address>

并且试图验证 XML 的代码在这里(注意 XML 文件被反序列化成的 "address" class 是一个自动从 xsd.exe 生成 class):

address address;
var xmlSchemaSerializer = new XmlSerializer(typeof(XmlSchema));
var addressXmlSerializer = new XmlSerializer(typeof(address));

var schemas = new XmlSchemaSet();
XmlSchema schema;
using (var xsdStream = File.OpenRead("address-schema.xsd"))
{
    schema = (XmlSchema)xmlSchemaSerializer.Deserialize(xsdStream);
}
schemas.Add(schema);
var settings = new XmlReaderSettings
{
    Schemas = schemas,
    ValidationType = ValidationType.Schema,
    ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings | XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ProcessSchemaLocation
};
settings.ValidationEventHandler += (sender, arguments) =>
{
    throw new XmlSchemaValidationException(arguments.Message);
};

using(Stream addressXmlStream = File.OpenRead("address-doc.xml"))
using (XmlReader reader = XmlReader.Create(addressXmlStream, settings))
{
    address = (address)addressXmlSerializer.Deserialize(reader);
}
Console.WriteLine(address.firstName.first.Value == "Some" ? "Success!" : "Fail");
Console.ReadKey();

ValidationEventHandler 中抛出异常('System.Xml.Schema.XmlSchemaValidationException'全局元素'http://tempuri.org/address-schema.xsd:address'已声明。)。 任何帮助或建议将不胜感激。提前致谢!

您的异常的原因是您的文档有加载架构的架构位置提示,但您已经加载了它。

要么不预加载架构,要么从文档中删除 xsi:schemaLocation 属性。