我有这个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 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,但是我找不到我的错误,所以有人可以请你停下来吗?
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 :(得分: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有一个错误,当你找到第一个IDZ = AWak时 - 接下来你的步骤是取1个元素Take(1)
,所以在这个Take(1)
之后只返回一个元素的集合,所以接下来您的步骤TakeWhile(...)
使用这一个元素对集合进行操作,而不是后面的其余元素。