C# 利用高阶节点属性linq进行过滤
我正在尝试序列化新创建的对象并将其插入C# 利用高阶节点属性linq进行过滤,c#,linq,linq-to-xml,C#,Linq,Linq To Xml,我正在尝试序列化新创建的对象并将其插入XDocument的特定子节点。我已经设法做到了这一点,但我的代码似乎很臭 我怎样才能针对更高的节点属性值进行测试,而不必像下面所做的那样通过Parent属性进行链接 XDocument xdoc = XDocument.Load(path); var elements = ( from doc in xdoc.Descendants("Unit") where doc.Parent.Parent.Attribute("name").Val
XDocument
的特定子节点。我已经设法做到了这一点,但我的代码似乎很臭
我怎样才能针对更高的节点属性值进行测试,而不必像下面所做的那样通过Parent
属性进行链接
XDocument xdoc = XDocument.Load(path);
var elements = (
from doc in xdoc.Descendants("Unit")
where doc.Parent.Parent.Attribute("name").Value == _UnitTypeName &&
doc.Parent.Parent.Parent.Parent.Attribute("name").Value == _UnitCategoryN
doc.Parent.Parent.Parent.Parent.Parent.Parent.Attribute("name").Value ==
select doc
);
foreach (var element in elements)
{
Unit unit =
new Unit
{
Armour = _Armour,
Attacks = _Attacks,
BallisticSkill = _BallisticSkill,
Composition = _Composition,
DedicatedTransport = _DedicatedTransport,
Initiative = _Initiative,
Leadership = _Leadership,
Options = _Options,
SaveThrow = _SaveThrow,
SpecialRules = _SpecialRules,
Strength = _Strength,
Toughness = _Toughness,
UnitName = _UnitName,
Weapons = _Weapons,
WeaponSkill = _WeaponSkill,
Wounds = _Wounds,
Points = _Points
};
XmlSerializer serializer = new XmlSerializer(typeof(Unit));
using (var stream = new MemoryStream())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(stream, unit, ns);
stream.Position = 0;
//using (XmlReader reader = XmlReader.Create(stream))
//{
// XElement xe = XElement.Load(reader);
XElement xe = XElement.Load(@"C:\Test\tempfile.xml"); // For some reason loading via MemoryStream messes with xml formatting
element.AddBeforeSelf(xe);
//}
}
break;
}
xdoc.Save(path);
这是XML文档的结构:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfArmy>
<Army name="Tyranid">
<unit-category>
<UnitCategory name="Troops">
<unit-type>
<UnitType name="Infantry">
<unit>
<Unit points="5" name="Hornmagant" composition="20" weapon-skill="3" ballistic-skill="100" strength="3" toughness="4" wounds="1" initiative="3" attacks="3" leadership="5" saving-throw="6+" armour="Chitin" weapons="Many" special-rules="None" dedicated-transport="No" options="8">
<Amount>0</Amount>
</Unit>
<Unit points="5" name="Termagant" composition="20" weapon-skill="3" ballistic-skill="100" strength="3" toughness="4" wounds="1" initiative="3" attacks="3" leadership="5" saving-throw="6+" armour="Chitin" weapons="Many" special-rules="None" dedicated-transport="No" options="8">
<Amount>0</Amount>
</Unit>
</unit>
</UnitType>
</unit-type>
</UnitCategory>
</unit-category>
</Army>
</ArrayOfArmy>
0
0
您可以使用,这类似于使用嵌套的foreach
循环:
var elements = (
from army in xdoc.Descendants("Army")
where army.Attribute("name").Value == _ArmyName
from unitCategory in army.Descendants("UnitCategory")
where unitCategory.Attribute("name").Value == _UnitCategoryName
from unitType in unitCategory.Descendants("UnitType")
where unitType.Attribute("name").Value == _UnitTypeName
from unit in unitType.Descendants("Unit")
select unit
);
注意:方法语法等价于谢谢!使用带有
where
过滤器的复合for子句可以获得相同的结果,可读性更高@友好:我很高兴你从我的回答中得到了你所需要的。为了避免让未来的读者感到困惑,我想确保我的查询与您的原始查询匹配。我编辑的答案是您的新查询的样子吗?我对XML不是很有经验,大写和小写的名称让我很反感。带有连字符的节点没有属性,因此我会得到一个空引用来查询它们的名称。这些节点表示序列化的列表。我不得不随机插入一些/
,以限制编辑字符。