XmlSchemaValidationException:这是一个无效的xsi:类型"Book",当尝试反序列化使用XSD架构验证XML时



我有一个带有LibraryAssets数组的xml,它们是Books、Newspapers和Patents,LibraryAsset是它们派生的抽象类。我使用visualstudio的Create模式创建了一个基于xml的xsd模式。但是,当我尝试反序列化xml以验证它是否与模式匹配时,我会得到以下错误:

System.InvalidOperationException : There is an error in XML document (3, 4).
----> System.Xml.Schema.XmlSchemaValidationException : This is an invalid xsi:type 'Book'.
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)

我的xsd模式:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xsd:element name="ArrayOfLibraryAsset">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="LibraryAsset">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Id" type="xsd:unsignedInt" />
<xsd:element name="Name" type="xsd:string" />
<xsd:element name="YearPublished" type="xsd:unsignedShort" />
<xsd:element name="PagesNumber" type="xsd:unsignedByte" />
<xsd:element name="Annotation" type="xsd:string" />
<xsd:element name="Price" type="xsd:unsignedByte" />
<xsd:element minOccurs="0" name="Number" type="xsd:string" />
<xsd:element minOccurs="0" name="Inventors">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="string" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="Country" type="xsd:string" />
<xsd:element minOccurs="0" name="ApplicationDate" type="xsd:dateTime" />
<xsd:element minOccurs="0" name="StandardNumber" type="xsd:string" />
<xsd:element minOccurs="0" name="Authors">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="string" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="CityPublished" type="xsd:string" />
<xsd:element minOccurs="0" name="Publisher" type="xsd:string" />
<xsd:element minOccurs="0" name="CopiesNumber" type="xsd:unsignedShort" />
<xsd:element minOccurs="0" name="Issue" type="xsd:unsignedByte" />
<xsd:element minOccurs="0" name="IssueDate" type="xsd:dateTime" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xs:schema>

Xml文件:

<?xml version="1.0"?>
<ArrayOfLibraryAsset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LibraryAsset xsi:type="Book">
<Id>62915385</Id>
<Name>Unspecified</Name>
<YearPublished>2000</YearPublished>
<PagesNumber>200</PagesNumber>
<Annotation>No annotation.</Annotation>
<Price>50</Price>
<StandardNumber>000-0-00-000000-0</StandardNumber>
<Authors>
<string>Author</string>
</Authors>
<CityPublished>Unspecified</CityPublished>
<Publisher>Unspecified</Publisher>
<CopiesNumber>300</CopiesNumber>
</LibraryAsset>
<LibraryAsset xsi:type="Newspaper">
<Id>57188600</Id>
<Name>Unspecified</Name>
<YearPublished>2021</YearPublished>
<PagesNumber>25</PagesNumber>
<Annotation>No annotation.</Annotation>
<Price>5</Price>
<StandardNumber>0000-0000</StandardNumber>
<CityPublished>Unspecified</CityPublished>
<Publisher>Unspecified</Publisher>
<CopiesNumber>1500</CopiesNumber>
<Issue>10</Issue>
<IssueDate>2021-11-19T00:00:00+04:00</IssueDate>
</LibraryAsset>
<LibraryAsset xsi:type="Patent">
<Id>14464371</Id>
<Name>Unspecified</Name>
<YearPublished>2021</YearPublished>
<PagesNumber>50</PagesNumber>
<Annotation>No annotation.</Annotation>
<Price>10</Price>
<Number>X0000000</Number>
<Inventors>
<string>Inventor</string>
</Inventors>
<Country>Unspecified</Country>
<ApplicationDate>2021-11-19T00:00:00+04:00</ApplicationDate>
<IssueDate>2021-11-18T19:34:16.5902406+04:00</IssueDate>
</LibraryAsset>
</ArrayOfLibraryAsset>

Xml反序列化:

var schemas = new XmlSchemaSet();
schemas.Add(null, shemaFilePath);
Exception exception = null;
var settings = new XmlReaderSettings
{
Schemas = schemas,
ValidationType = ValidationType.Schema,
ValidationFlags =
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ReportValidationWarnings
};
settings.ValidationEventHandler += delegate (object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
{
_log.Warning(args.Message);
}
else
{
exception ??= args.Exception;
_log.Error(exception);
throw exception;
}
};
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using var xmlReader = XmlReader.Create(fileStream, settings);
var xmlSerializer = new XmlSerializer(typeof(List<T>));
data = xmlSerializer.Deserialize(xmlReader) as List<T>;

因此,您的模式生成器有一个限制,即它忽略xsi:type属性。这并不奇怪,很难知道这会对他们产生什么影响。

很明显,你知道该工具所不知道的东西("LibraryAssets是图书、报纸和专利,LibraryAsset是它们派生的抽象类"(,通常情况下,当你生成一个模式时,你得到的只是第一个片段,你需要对其进行编辑,以考虑到你对应用程序域语义的了解。

解决方案比我想象的要简单得多。

所以,基本上,我只需要声明每种类型(书籍、报纸、专利是抽象LibraryAsset的扩展(。最终解决方案XSD如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xs:element name="LibraryAsset" type="LibraryAsset" abstract="true"/>
<xs:element name="Book" type="Book"/>
<xs:element name="Newspaper" type="Newspaper"/>
<xs:element name="Patent" type="Patent"/>
<xsd:complexType name="LibraryAsset" abstract="true">
<xsd:sequence>
<xsd:element name="Id" type="xsd:int" />
<xsd:element name="Name" type="xsd:string" />
<xsd:element name="YearPublished" type="xsd:int" />
<xsd:element name="PagesNumber" type="xsd:int" />
<xsd:element name="Annotation" type="xsd:string" />
<xsd:element name="Price" type="xsd:int" />
<xsd:element minOccurs="0" name="Number" type="xsd:string" />
<xsd:element minOccurs="0" name="Inventors">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="string" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="Country" type="xsd:string" />
<xsd:element minOccurs="0" name="ApplicationDate" type="xsd:dateTime" />
<xsd:element minOccurs="0" name="StandardNumber" type="xsd:string" />
<xsd:element minOccurs="0" name="Authors">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="string" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element minOccurs="0" name="CityPublished" type="xsd:string" />
<xsd:element minOccurs="0" name="Publisher" type="xsd:string" />
<xsd:element minOccurs="0" name="CopiesNumber" type="xsd:int" />
<xsd:element minOccurs="0" name="Issue" type="xsd:int" />
<xsd:element minOccurs="0" name="IssueDate" type="xsd:dateTime" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Book">
<xsd:complexContent>
<xsd:extension base="LibraryAsset">
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Newspaper">
<xsd:complexContent>
<xsd:extension base="LibraryAsset">
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Patent">
<xsd:complexContent>
<xsd:extension base="LibraryAsset">
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="ArrayOfLibraryAsset">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="LibraryAsset">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xs:schema>

最新更新