2013-04-07 100 views
0

我有这样的XML的LINQ to XML skipwhile()takewhile()

<root> 
<TR_ZAL IDZ="cOY9" O="0"> 
</TR_ZAL> 
<TR_ZAL IDZ="FOXd" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="wAW5" O="1"> 
<TR_ZAL IDZ="AWak" O="1"> 
</TR_ZAL> 
<TR_ZAL IDZ="XpPp" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="asTu" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="y9VV" O="1"> 
</TR_ZAL> 
</root> 

,我知道IDZ"AWak",我的任务是让已知IDZ和所有之后的元素,直至与相同的下一个元素属性O,如果没有其他人,那么我应该得到所有剩余的元素。在这种情况下,它应该是

<TR_ZAL IDZ="AWak" O="1"> 
</TR_ZAL> 
<TR_ZAL IDZ="XpPp" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="asTu" O="10"> 
</TR_ZAL> 

所以我试图使用LINQ,但我找不到我的错误,所以任何人都可以请HALP我吗?

IEnumerable<XElement> rozsah = xmlText.Root.Elements("TR_ZAL") 
        .SkipWhile(x => x.Attribute("IDZ").Value != "AWak") 
        .Take(1) 
        .TakeWhile(x =>Convert.ToInt32(x.Attribute("O").Value) != o); 
+0

您的输入XML无效(并非所有TR_ZAL都已关闭标记)。你能解决它吗?你有层次结构吗?或者一切都只是一个TR_ZAL列表? – outcoldman 2013-04-07 23:51:48

+0

哦,我很抱歉,由于复制粘贴错误,xml无效 – david 2013-04-08 00:24:27

回答

1

我猜你的XML应该是有效的这种变化:

<root> 
<TR_ZAL IDZ="cOY9" O="0"> 
</TR_ZAL> 
<TR_ZAL IDZ="FOXd" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="wAW5" O="1"> 
</TR_ZAL> 
<TR_ZAL IDZ="AWak" O="1"> 
</TR_ZAL> 
<TR_ZAL IDZ="XpPp" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="asTu" O="10"> 
</TR_ZAL> 
<TR_ZAL IDZ="y9VV" O="1"> 
</TR_ZAL> 
</root> 

如果这是真的,然后回答下面的问题:

int? o = null; 
IEnumerable<XElement> rozsah = xmlText.Root 
    // Getting all child 'TR_ZAL' from root object 
    .Elements("TR_ZAL") 
    // Ignoring until we will not meet TR_ZAL with IDZ == AWak 
    .SkipWhile(x => x.Attribute("IDZ").Value != "AWak") 
    // Cache the first value of elements in collection and compare each next item 
    // we want to take only items which does not have the same value 
    .TakeWhile(x => 
     { 
      int oAttributeValue = XmlConvert.ToInt32(x.Attribute("O").Value); 

      if (!o.HasValue) 
      { 
       o = oAttributeValue; 
       return true; 
      } 
      else 
      { 
       return o != oAttributeValue; 
      } 
     }); 

你LINQ有一个bug当你找到第一个IDZ = AWak时 - 接下来你的步骤是取1个元素Take(1),所以在这个Take(1)之后你将只返回一个元素的集合,所以接下来你的步骤TakeWhile(...)使用这一个元素对集合进行操作,而不是对其他元素进行操作。

+0

谢谢我认为'take(1)'只需一个元素并移动光标,但现在我明白了 – david 2013-04-08 00:25:36