这是我的XML文件:
<Applications>
<Application Name="Abc">
<Section Name="xyz">
<Template Name="hello">
...
....
</Template>
</Section>
</Application>
<Application Name="Abc1">
<Section Name="xyz1">
<Template Name="hello">
...
....
</Template>
</Section>
</Application>
我需要做的是根据Template标签的Name属性从给定结构中获取Template XElement。问题是可以有多个具有相同属性Name的模板标签。区别因素是Application Name属性值和section属性值。
目前我能够通过首先根据它的属性获取应用程序元素来获取XElement,然后根据它的属性获取Section,然后根据它的名称获得最终模板。
我想知道是否有办法一次性完成它。
答案 0 :(得分:6)
我会使用你可以调用Elements
或现有序列的事实,所以:
var template = doc.Descendants("Application")
.Where(x => (string) x.Attribute("Name") == applicationName)
.Elements("Section")
.Where(x => (string) x.Attribute("Name") == sectionName)
.Elements("Template")
.Where(x => (string) x.Attribute("Name") == templateName)
.FirstOrDefault();
您甚至可能想在某处添加扩展方法:
public static IEnumerable<XElement> WithName(this IEnumerable<XElement> elements,
string name)
{
this elements.Where(x => (string) x.Attribute("Name") == name);
}
然后您可以将查询重写为:
var template = doc.Descendants("Application").WithName(applicationName)
.Elements("Section").WithName(sectionName)
.Elements("Template").WithName(templateName)
.FirstOrDefault();
...我认为你会同意这一点很可读:)
请注意,使用XAttribute
转换为string
而非使用Value
属性意味着任何没有Name
属性的元素都会被有效忽略而不是导致NullReferenceException
。
答案 1 :(得分:1)
XDocument doc = XDocument.Load("Path of xml");
var selection =
doc.Descendants("Section").Select(item => item).Where(
item => item.Attribute("Name").Value.ToString().Equals("Section Name Value")).ToList();
if(null != selection)
{
var template =
selection.Descendants("Template").Select(item => item).Where(
item => item.Attribute("Name").Value.ToString().Equals("Template name value"));
}
答案 2 :(得分:1)
以下代码可以解决这个问题:
var template = doc.Descendants("Template")
.Where(x => x.Attribute("Name").Value == "hello"
&& x.Parent.Attribute("Name").Value == "xyz1"
&& x.Parent.Parent.Attribute("Name").Value == "Abc1");
请注意,如果XML不符合规范,此代码会抛出异常。具体来说,如果有问题的任何标签不包含名为“Name”的属性,则会有NullReferenceException
。或者,如果模板标签没有两级父母。
答案 3 :(得分:1)
XPath应该可以帮到你。使用Extensions.XPathSelectElement Method (XNode, String):
XDocument xdoc = XDocument.Load("yourfile.xml");
string xPathQuery = string.Format(
"/Applications/Application[@Name='{0}']/Section[@Name='{1}']/Template[@Name='{2}']",
"MyApplication",
"MySection",
"MyTemplate"
);
XElement template = xdoc.Root.XPathSelectElement(xPathQuery);