[英]How to improve XSD validation verbosity
我已經通過使用XmlDocument.Validate(ValidationEventHandler)
, XDocument.Validate(schemas, ValidationEventHandler)
和XmlReader
探索了使用xsd進行的各種類型的xml驗證,並傳遞了將結果發送到ValidationEventHandler
回調的模式。
但是,回調實際上僅提供嚴重性和錯誤字符串。 正在接收類似這樣的消息:
The 'name' attribute is invalid - The value '' is invalid according to
its datatype 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd' - The
Pattern constraint failed.
現在離理想的錯誤消息還很遠。 回調args不提供導致此問題的原因,也不提供它的XML行或任何實際的方法。
在我的場景中,並非所有名稱都是上面給定的類型,其中一些名稱可以是空字符串(因為它們是可選的)。
現在可能已經有數百個具有名稱的xml節點,這使查找上述問題變得非常煩人,因為沒有有關該位置的上下文信息,甚至沒有xml節點是什么。
這種驗證的冗長性如何擴展? 例如,Notepad ++使用XML Tools插件,將上述消息輸出為:
使用XML模式驗證當前文件:
ERROR: Element 'LightSource', attribute 'name': [facet 'minLength'] The value '' has a length of '0'; this underruns the allowed minimum length of '1'.
ERROR: Element 'LightSource', attribute 'name': [facet 'pattern'] The value '' is not accepted by the pattern '.*\S'.
ERROR: Element 'LightSource', attribute 'name': '' is not a valid value of the atomic type 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd'.
這更加冗長,它表明至少有一些上下文信息(例如問題)出現在LightSource元素上,以及底層類型究竟有什么問題。
是否還有其他設施可以通過增加的上下文信息來進行正確的C#XSD驗證?
根據XDocument
和XmlDocument
對XML的內存中表示形式進行了驗證,並使用XmlReader
從文件中進行了讀取。 顯然,行號等僅在已經寫入xml文件的上下文中才有意義,但是其他信息(如父元素等)將很方便,因此我至少可以將xml上下文輸出到要查看的地方。
為了完整起見,一些代碼:
var schemas = new XmlSchemaSet();
schemas.Add("", xsdPath);
var doc = XDocument.Load(xmlFile);
doc.Validate(schemas,ValidationEventHandler);
public void ValidationEventHandler(object sender, ValidationEventArgs e)
{
// Not much in e
switch (e.Severity)
{
case XmlSeverityType.Error:
Console.WriteLine("Error: {0}", e.Message);
break;
case XmlSeverityType.Warning:
Console.WriteLine("Warning {0}", e.Message);
break;
}
}
看起來很有希望的另一種嘗試是http://msdn.microsoft.com/en-us/library/as3tta56%28v=vs.110%29.aspx,但絲毫沒有增加任何冗長的含義。
我有一些構成約束的類型:
<xs:simpleType name="TNonEmptyStringNoWhitespacesAtBeginn"> <xs:restriction base="xs:string"> <xs:pattern value="\\S.*" /> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="TNonEmptyStringNoWhitespacesAtBeginningAndEnd"> <xs:restriction base="TNonEmptyStringNoWhitespacesAtBeginn"> <xs:pattern value=".*\\S" /> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType>
忽略TNonEmptyStringNoWhitespacesAtBeginn
它是允許AND限制的助手。 因此,當我具有上面類型的屬性name
時,它只是一個空字符串,我從C#的XSD驗證以及Notepads ++ XML工具插件所做的事情中獲得的信息量截然不同。 為了完整起見,以下是不同的消息:
C#
ERROR: Element 'LightSource', attribute 'name': [facet 'minLength'] The value '' has a length of '0'; this underruns the allowed minimum length of '1'.
ERROR: Element 'LightSource', attribute 'name': [facet 'pattern'] The value '' is not accepted by the pattern '.*\S'.
ERROR: Element 'LightSource', attribute 'name': '' is not a valid value of the atomic type 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd'.
記事本+ +
ERROR: Element 'LightSource', attribute 'name': [facet 'minLength'] The value '' has a length of '0'; this underruns the allowed minimum length of '1'. ERROR: Element 'LightSource', attribute 'name': [facet 'pattern'] The value '' is not accepted by the pattern '.*\\S'. ERROR: Element 'LightSource', attribute 'name': '' is not a valid value of the atomic type 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd'.
利用異常內容提供的信息,我可以檢索XML元素並顯示它,但是說TNonEmptyStringNoWhitespacesAtBeginningAndEnd
失敗的約束TNonEmptyStringNoWhitespacesAtBeginningAndEnd
沒有告訴我詳細的哪部分失敗了。 我知道我得到的提示是,模式約束失敗了,但是任何收到這種消息的人都需要找到類型並檢查其約束以獲取有關約束的知識。 通過檢查異常中的數據,似乎這就是這里的詳細程度。
XML Tools Plugin似乎可以公開每個驗證項目,並且具有更多詳細信息。 這不僅僅是從XSD推論得出的,它看起來像是通過每個約束的處理步驟獲得的信息。
我希望的是一種增加驗證器的詳細程度以獲得更多信息的方法。
Re:行號...對於XDocument,如果啟用了行信息捕獲
XDocument xdoc = XDocument.Load(reader, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo | LoadOptions.SetBaseUri);
那么您的驗證處理程序將在您發布的ValidationEventHandlercode( IXmlLineInfo )中提取類似以下內容:
IXmlLineInfo node = sender as IXmlLineInfo;
if (node != null && node.HasLineInfo()) ...
這應該涵蓋您想要的信息...
對於傳統的DOM,您可以選擇檢查Exception屬性(為您提供LineNumber和LinePosition ),至少在理論上,通過Exception屬性,您還可以獲取SchemaObjectProperty 。 在我的所有代碼中,我都在使用XDocument,並且可以肯定地運行良好。
這應該使您開始至少提供一個更好的行/位置位置(即使它在內存中也可以使用)。
(根據修改后的問題進行更新)
C#不會為您提供您所指的插件所看到的內容……對我來說,這是一種實現選擇。 XSD方面可以協同工作; 因此,任何失敗都將整體視為無效。
.NET的內置XSD驗證器是通用的,不需要太多的驗證調整(唯一的一項是執行或不執行唯一粒子歸因)。 為了平衡性能,以上操作僅適用於簡單的類型驗證。
該插件似乎是為交互性而設計的...無論需要什么,它似乎都想盡可能多地講述...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.