我有一個包含一系列 LibraryAssets 的 xml,它們是書籍、報紙和專利,而 LibraryAsset 是它們派生的抽象類。我使用 Visual Studio 的創建架構基于該 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>;
uj5u.com熱心網友回復:
因此,您的模式生成器具有忽略xsi:type屬性的限制。這不是一個很大的驚喜,很難知道它會用它們做什么。
您顯然知道該工具不知道的一些東西(“LibraryAssets 是書籍、報紙和專利,LibraryAsset 是它們派生自的抽象類”)并且通常的做法是,當您生成模式時,您得到的只是第一次切割,并且您應該編輯它以考慮您對應用程式域語意的了解。
uj5u.com熱心網友回復:
解決方案比我想象的要簡單得多。
所以,基本上,我只需要宣告每種型別(書籍、報紙、專利是抽象 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>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/363076.html
上一篇:如果找到資料,如何創建條件陳述句來對這些資料進行排序并應用模板?
下一篇:使用python進行XML驗證
