2012-03-01 76 views
0

我有一個解析XML文檔,它不遵循任何種類的固定模式。我需要通過這樣的方式解析出值:容錯XML解析

invoiceDetail.PartNO = invoiceLine.Element(ns + "Item").Element(ns + "ItemID").Element(ns + "ID").Value; 

在此示例中,invoiceLine是XElement類型。問題是有些節點並不總是存在,在這種情況下,我寧願返回null或空而不返回錯誤。有什麼辦法可以做到這一點,或者我應該自己做一個特殊的函數,它需要一個命名空間和元素名稱列表來嘗試解析?

+0

如果它不遵循任何標準,它不能是XML(這是一個標準)。 – Oded 2012-03-01 17:15:10

+0

@Oded - 那你會怎樣稱呼它?它遵循每個開標籤結束標籤的標準。問題是,它重複使用多個級別的標籤名稱,並在同一級別重複使用不同名稱的標籤。它也有標籤,可能會或可能不會出現在同一類型的不同文檔中。 – 2012-03-01 19:39:00

+0

說它不符合任何標準,但它是XML是誤導。如果它是格式良好的XML,它就是格式良好的XML並遵循這個標準。如果您的意思是它沒有固定的模式,並且無法針對模式進行驗證,那是不同的。 – Oded 2012-03-01 19:40:07

回答

2

XLINQ已經這樣做了。
.Element()將返回null如果沒有該名稱的元素。

爲了避免重複null檢查,使用.Elements()代替:

invoiceDetail.PartNO = (string) 
    invoiceLine.Elements(ns + "Item") 
       .Elements(ns + "ItemID") 
       .Elements(ns + "ID") 
       .SingleOrDefault(); 

每個Elements()調用將返回一個IEnumerable<XElement>。如果沒有任何匹配的元素,它將返回一個空序列,其餘的代碼仍然可以工作。

.SingleOrDefault()將最終序列轉換爲單個元件或null
(string)強制轉換調用一個自定義顯式轉換,如果該元素爲null,則該轉換應該返回null。您也可以直接將其轉換爲基本值類型。

+0

對,但是如果我需要深入3個元素,我必須先檢查.Element()的每個結果,然後才能進入下一個,最後,我必須檢查最後一個.Element()是否爲null,然後才能獲得我的價值或我結束了一個錯誤。 – 2012-03-01 17:22:22

+1

@RandomBen:改爲調用'.Elements()'(複數)。這樣,你會得到一個空集合而不是'null'。 – SLaks 2012-03-01 17:24:07

+1

是否可以使用invoiceLine.Descendants(「ID」)。它會返回所有「ID」元素,而不考慮結構。 – 2012-03-01 18:22:05