2011-03-15 54 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