2011-03-15 51 views
1

我試圖根據該元素的子元素的屬性選擇元素。通過後代元素的屬性過濾XElements

原始的XML:

<Root> 
     <Element1 id="1"> 
     <element2>XXXX</element2> 
     <element3>XXXX</element3> 
     <element4>XXXX</element4> 
     <Filter attr1="1" attr2="0" attr3="0" attr4="1" attr5="0"></Filter> 
     </Element1> 
     <Element1 id="2"> 
     <element2>XXXX</element2> 
     <element3>XXXX</element3> 
     <element4>XXXX</element4> 
     <Filter attr1="1" attr2="0" attr3="1" attr4="1" attr5="0"></Filter> 
     </Element1> 
     <Element1 id="3"> 
     <element2>XXXX</element2> 
     <element3>XXXX</element3> 
     <element4>XXXX</element4> 
     <Filter attr1="1" attr2="1" attr3="0" attr4="1" attr5="0"></Filter> 
     </Element1> 
    </Root> 

這是我迄今所做的:

Dim xmlElement = (From rec In RecipeXmlDocument.Descendants("Element1") _ 
Where (rec.Descendants("Filter")[email protected]= "1" _ 
        Or rec.Descendants("Filter")[email protected] = "0" _ 
        Or rec.Descendants("Filter")[email protected] = "0" _ 
        And (rec.Descendants("Filter")[email protected] = "1" _ 
         Or rec.Descendants("Filter")[email protected] = "0" _ 

這引發以下錯誤:「類型 'System.Linq.SystemCore_EnumerableDebugViewEmptyException' 引發的異常「。

代碼試圖做的是選擇所有Element1s,其中element1的過濾元素與語句的where子句相匹配。

我對linq相當陌生,我不確定我做錯了什麼。

回答

0

這是一種情況下,XPath可能會產生正確的結果比用LINQ做的工作要少。你可以制定一個XPath查詢,如:

/Root/Element1[Filter[(@attr1 = '1' or @attr2 = '0' or @attr3 = '0') 
        and (@attr4 = '1' or @attr5 = '0')]] 

(我加了周圍聯體與or測試括弧裏,因爲我懷疑這是你想要的,但我可能是錯的。)這會發現有一個Filter所有Element1元素子元素的屬性通過所描述的謂詞。

然後,你可以通過使用XDocument.XPathSelectElements()只是遍歷這些元素:

var elements = doc.XPathSelectElements(xpath); 
0

我想你應該進入這個方向:

RecipeXmlDocument.Root.Elements() 
.Where(e => e.Elements("Filter").SingleOrDefault([filter conditions]) != null); 

這需要在root下的所有元素,其中一個名爲「過濾器」單個子元素相匹配的[過濾條件。如果不存在這樣的子元素,則SingleOfDefault將返回null,因此Where子句爲假,並且不包括該元素。

根據您的情況,您可能需要稍微微調一下。

[過濾條件]可能是這樣的:

f => f.Attribute("attr1").Value == "1" && f.Attribute("attr2").Value == "2" 

UPDATE:我試圖將其轉換爲VB.net(手指交叉):

Dim xmlElement = 
(From rec In RecipeXmlDocument.Descendants("Element1") _ 
Where not (From filter in rec.Elements("Filter").Any(_ 
Function(f) f.Attribute("attr1") = "1" And f.Attribute("attr2") = "2") is Nothing) 

極有可能這不會編譯和你需要作出調整,但我希望它可以幫助:)

+0

而不是'SingleOrDefault'你想要的東西像'Any',因爲它的名字居然說什麼它打算在這裏做。 – Gabe 2011-03-15 07:53:23

+0

這看起來很有希望,但我努力將語句轉換爲vb.net。 – Martinffx 2011-03-15 10:18:29

+0

@Martinffx,是的,我很害怕這個,它是C#,你的代碼是VB,因此我提到了「微調」。我不知道VB和Linq的表達式語法足以將其轉換。我希望VB也有一個方法語法,你可以以某種方式推斷我的意思。不幸的是,我會給它一個看看是否有幫助。 – Bazzz 2011-03-16 14:12:32