简体   繁体   English

LINQ查询以在不存在属性时获取XML元素

[英]LINQ query to get XML elements when an attribute is not present

I have this XML: 我有这个XML:

<Config>
  <EmpFieldsMap>
    <Employee>
      <Field>
        <Name update = "false">EmpNumber</Name>
      </Field>
      <Field>
        <Name insert = "true">EmpName</Name>
      </Field>
      <Field>
        <Name insert = "true">EmpDesignation</Name>
      </Field>
    </Employee>
  </EmpFieldsMap>
</Config>

My application will do an an INSERT or UPDATE for which the fields will come from this xml. 我的应用程序将执行INSERT或UPDATE,其字段将来自此xml。 Each tag will have either the insert or the update attribute as shown in the snippet above. 每个标签都将具有insert或update属性,如上面的代码片段所示。

For Insert all the tags that have the attribute 对于插入具有属性的所有标签

insert = "true"

and the tags that don't have this attribute, in this case the 'EmpNumber', have to be considered. 并且必须考虑不具有此属性的标签(在这种情况下为“ EmpNumber”)。

The same applies for update. 更新同样如此。

This code gives me all the tags with the insert attribute set to true: 这段代码为我提供了insert属性设置为true的所有标签:

insertTags = from p in xml.Element("Config").Element("EmpFieldsMap").Elements("Field")
             where p.Element("Name").Attribute("insert") != null 
             && p.Element("Name").Attribute("insert").Value == "true"
             select p.Element("Name").Value;

Removing the check for null 删除空值检查

insertTags = from p in xml.Element("Config").Element("EmpFieldsMap").Elements("Field")
             where p.Element("Name").Attribute("insert").Value == "true"
             select p.Element("Name").Value;

gives

Object Reference not set to an instance 对象引用未设置为实例

error. 错误。

I am having trouble composing a query that will also include the tags where the attribute is not present. 我在编写查询时遇到麻烦,该查询还将包含不存在该属性的标签。

Can someone please help me with this? 有人可以帮我吗?

Regards. 问候。

insertTags = from p in xml.Element("Config").Element("EmpFieldsMap").Elements("Field")
    where (p.Element("Name").Attribute("insert") ?? "true") == "true"
    select p.Element("Name").Value;

With XPath and Linq it even simpler: 使用XPath和Linq,它甚至更简单:

XPathSelectElements(@"Config/EmpFieldsMap/Employee/Field/Name[@insert='true']")

Also for this particular xml you can use global search for name elements: 同样对于这个特定的xml,您可以使用全局搜索来查找名称元素:

var insertTags = xdoc.XPathSelectElements(@"//Name[@insert='true']")
                     .Select(n => (string)n);

Or with Linq query syntax: 或使用Linq查询语法:

var insertTags = from n in xdoc.Descendants("Name")
                 where (string)n.Attribute("insert") == "true"
                 select (string)n;

When you cast node value to string, it will not throw exception if node is missing. 将节点值转换为字符串时,如果缺少节点,则不会引发异常。 Simply null will be returned. 简单地将返回null So, you don't need all that stuff (which is btw even not compilable ): 因此,您不需要所有这些东西(顺便说一句,甚至是不可编译的 ):

(p.Element("Name").Attribute("insert") ?? "true") == "true"

One more edit . 再编辑一遍 If you are dealing with booleans, then use booleans instead of strings: 如果要处理布尔值,请使用布尔值而不是字符串:

var insertTags = from n in xdoc.Descendants("Name")
                 where (bool?)n.Attribute("insert") == true
                 select (string)n;

How it works? 这个怎么运作? Nullable boolean will have null value for missing attributes. 可为空的布尔值将对缺少的属性具有null值。 Comparing bool? 比较bool? which do not have value with any boolean value produces false . 没有任何布尔值的值将生成false So, you will get only those elements, which have required attribute, and which have true for that attribute. 因此,您将仅获得具有必需属性且对该属性具有true那些元素。

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

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