繁体   English   中英

获取XML的XElement

[英]Get the XElement for the XML

这是我的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,然后根据它的名称获得最终模板。

我想知道是否有办法一次性完成它。

我会使用你可以调用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强制XAttributestring而不是使用Value属性意味着任何没有Name属性的元素都会被有效地忽略,而不是导致NullReferenceException

    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"));
    }

以下代码应该可以解决问题:

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 或者,如果Template标签没有两级父母。

XPath应该会帮助你。 使用Extensions.XPathSelectElement方法(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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM