2014-01-15 40 views
2

我用XmlDocument.Validate(ValidationEventHandler)XDocument.Validate(schemas, ValidationEventHandler)XmlReader與傳遞給它的模式是將結果發送到ValidationEventHandler回調探索不同類型的XML驗證使用XSD。如何提高XSD驗證冗長

但是,回調實際上僅提供嚴重性和錯誤字符串。我收到這樣的消息,如:

The 'name' attribute is invalid - The value '' is invalid according to 
its datatype 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd' - The 
Pattern constraint failed. 

現在這遠離一個理想的錯誤消息。回調參數並沒有提供什麼父母導致這一點,也沒有提供什麼樣的XML線或任何實際的東西。

在我的場景中,並非所有名稱都是上述給定類型,其中一些名稱可能只是空字符串(因爲它們是可選的)。

現在有可能有數百個名稱爲xml的節點,這使得找到上述問題非常煩人,因爲沒有關於位置的上下文信息,甚至沒有xml節點。

如何延長這種驗證的冗長? 記事本++例如使用XML工具插件,輸出作爲上述消息:

當前文件的驗證使用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驗證?

驗證是根據XDocumentXmlDocument的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它是一個輔助允許和-ING限制。所以,當我有一個屬性name與上面的類型只是一個空字符串時,我從C#的XSD驗證和Notepads ++ XML工具插件做了非常不同的信息量。 下面是完整起見再次不同的消息:

C#

The 'name' attribute is invalid - The value '' is invalid according to 
its datatype 'TNonEmptyStringNoWhitespacesAtBeginningAndEnd' - The 
Pattern constraint failed. 

記事本++

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'. 

隨着由異常內容提供的信息I可以檢索XML元素,並顯示它但是表示TNonEmptyStringNoWhitespacesAtBeginningAndEnd失敗的限制要比告訴我哪部分細節失敗的表達要少得多。我知道我得到了提示,即模式約束失敗了,但是任何得到這樣的消息的人都需要定位類型並檢查它的約束以獲得關於約束的知識。通過檢查異常中的數據,這似乎是這裏的詳細程度。

XML工具插件似乎有能力公開每個驗證項目和更多的細節。這不是從XSD推斷出來的,而是看起來像通過每個約束的處理步驟獲得的信息。

我所希望的是一種增加驗證器的冗長度以獲得更多信息的方法。

回答

4

回覆:行號...有關的XDocument,如果啓用了行信息捕捉

那麼您的驗證處理程序將提取這樣的事情在你的貼ValidationEventHandlercode(IXmlLineInfo):

IXmlLineInfo node = sender as IXmlLineInfo; 
if (node != null && node.HasLineInfo()) ... 

這應該涵蓋你想要的信息...

對於傳統的DOM,你可以選擇檢查Exception屬性(給你LineNumberLinePosition),理論上至少通過Exception屬性,你也可以得到SchemaObjectProperty。在我使用XDocument的所有代碼中,這確實很好。

這應該讓你開始至少提供一個更好的位置線/位置(即使它在內存中也可以工作)。

(更新基於改進的問題)

C#不會給你什麼你看到你指的是插件...對我來說這是一個實現選擇。 XSD方面聯合工作;因此,任何失敗都認爲整個失效。

.NET的內置XSD驗證器是一個通用目的,沒有太多的驗證調整(唯一的一個是做或不是唯一粒子屬性)。爲了平衡性能,上述情況發生在簡單的類型驗證上。

插件似乎是專爲互動......它似乎想告訴儘可能多的,因爲它可以,不管什麼需要......

+0

這是highligly令人滿意。謝謝。我在第一次運行時檢查了pos和數字,但是我在新創建的內存中dom對象上做了這些,顯然沒有線路信息。 IXmlLineInfo確實幫助我。 – Samuel

+0

我剛剛意識到的問題仍然是開放的,是否可以根據約束失敗的哪個部分得到更深入的約束違約解釋。 – Samuel

+0

@Samuel,這最後一點......不在問題中,你的評論也不明確,你的意思也不清楚,你的意思是什麼。如果通過「約束的哪一部分失敗」,則表示導致異常的XSD組件......然後您可以嘗試檢查異常中的SchemaObject。但是,我不知道任何XSD感知處理器會根據行號/位置指示失敗的特定方面(枚舉,長度,最大長度等)......異常中的消息通常有助於指示失敗的情況。 .. –