[英]Validate XML against XSD using Saxon API C# not reporting all validation errors
我正在嘗試使用適用於 C#.Net 的 saxon api 針對 xsd 驗證 xml。 但是,它並不能一次性捕獲所有驗證錯誤。 所有違反數據類型的元素都會被捕獲,但如果結構形成錯誤且其中存在多個錯誤,則它只會捕獲第一個錯誤。 我創建了如下示例代碼
XSD文件
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:books" xmlns:bks="urn:books">
<xsd:element name="books" type="bks:BooksForm"/>
<xsd:complexType name="BooksForm">
<xsd:sequence>
<xsd:element name="book" type="bks:BookForm" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="BookForm">
<xsd:sequence>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="genre" type="xsd:string"/>
<xsd:element name="price" type="xsd:float" />
<xsd:element name="pub_date" type="xsd:date" />
<xsd:element name="review" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
文件
<?xml version="1.0"?>
<x:books xmlns:x="urn:books">
<book id="bk001">
<author>Writer</author>
<title>The First Book</title>
<genre>Fiction</genre>
<price>44.95</price>
<pub_date>2000-10-01</pub_date>
<review>An amazing story of nothing.</review>
</book>
<book id="bk002">
<author>Poet</author>
<title>The Poet's First Poem</title>
<genre>Poem</genre>
<price>ABC</price>
<review>Least poetic poems.</review>
</book>
<book id="bk003">
<bad_element_1></bad_element_1>
<bad_element_2></bad_element_2>
<author>Writer</author>
<title>The First Book</title>
<genre>Fiction</genre>
<price>ABC</price>
<pub_date>2000-10-01</pub_date>
<review>An amazing story of nothing.</review>
</book>
</x:books>
C#代碼
public void run(string xmlPath, string xsdPath)
{
EnterpriseConfiguration conf = new EnterpriseConfiguration();
conf.setConfigurationProperty(FeatureKeys.LICENSE_FILE_LOCATION, @"C:\saxon\saxon-license.lic");
Processor processor = new Processor(conf);
processor.SetProperty("http://saxon.sf.net/feature/timing", "true");
processor.SetProperty("http://saxon.sf.net/feature/validation-warnings", "false"); //Set to true to suppress the exception
SchemaManager manager = processor.SchemaManager;
manager.XsdVersion = "1.1";
List<Error> errorList = new();
manager.ErrorReporter = err => errorList.Add(err);
XmlReader xsdReader = XmlReader.Create(xsdPath);
try
{
manager.Compile(xsdReader);
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine("Schema compilation failed with " + errorList.Count + " errors");
foreach (Error error in errorList)
{
Console.WriteLine("At line " + error.Location.LineNumber + ": " + error.Message);
}
return;
}
SchemaValidator validator = manager.NewSchemaValidator();
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.ValidationType = ValidationType.Schema;
xmlReaderSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ReportValidationWarnings;
XmlReader xmlReader = XmlReader.Create(xmlPath, xmlReaderSettings);
Console.WriteLine("Validating input file " + xmlPath);
List<ValidationFailure> errors = new();
validator.InvalidityListener = failure => errors.Add(failure);
XdmDestination psvi = new();
validator.SetDestination(psvi);
try
{
validator.Validate(xmlReader);
}
catch (Exception e)
{
Console.WriteLine(e); Console.WriteLine(); Console.WriteLine();
Console.WriteLine("Instance validation failed with " + errors.Count + " errors"); Console.WriteLine(); Console.WriteLine();
foreach (ValidationFailure error in errors)
{
Console.WriteLine("At line " + error.LineNumber + ": " + error.Message); Console.WriteLine(); Console.WriteLine();
}
return;
}
Console.WriteLine("Input file is valid");
}
請幫忙。 謝謝。
我希望一次性捕獲所有驗證錯誤。
通常,如果元素的內容(子元素的序列)與架構中為該元素定義的內容模型不匹配,Saxon 會將其視為一個驗證錯誤,並且不會嘗試進一步驗證,直到它到達末尾無效元素。
從解析錯誤中恢復錯誤是一門藝術,沒有通用的解決方案; 人們討厭的一件事是錯誤地完成它會導致數百個虛假錯誤。
在您的特定示例中,您強調沒有報告 bad_element2 的錯誤。 但是處理器應該如何知道什么可以有效地跟隨 bad_element1? 架構沒有說。 您已經偏離了規則手冊,處理者無法在此處找到要應用的規則。
您可以采用架構在 bad_element1 之后不允許任何內容的方法,因此后面的任何內容都是另一個錯誤。 但這會導致許多您不想要的虛假錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.