C#使用XmlReader.Create对XSD反序列化和验证XML文件不起作用

时间:2017-04-26 19:36:09

标签: c# xml validation xsd xmlreader

我正在使用Visual Studio 2015。 我为名字不好的" firstName"而道歉。元件。它应该是" fullName",但由于我已经为模式生成了类,这只是为了我自己的学习,我把它保留原样。 我在这里有一个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文件被反序列化的&#34;地址&#34;类是来自xsd.exe的自动生成的类):

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();

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

1 个答案:

答案 0 :(得分:0)

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

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