LINQ to XML等同于XPath

Dan*_*ams 3 c# xpath linq-to-xml

我有解析XML的代码,如下所示:

<custom_fields>
  <custom_field>
      <column_name>foo</column_name>
    <column_value>0</column_value>
  <description>Submitted</description>
    <data_type>BOOLEAN</data_type>
    <length>0</length>
    <decimal>0</decimal>
  </custom_field>
  <custom_field>
    <column_name>bar</column_name>
    <column_value>0</column_value>
    <description>Validated</description>
    <data_type>BOOLEAN</data_type>
    <length>0</length>
    <decimal>0</decimal>
  </custom_field>
</custom_fields>
... more <custom_field> elements...
Run Code Online (Sandbox Code Playgroud)

我想找到被称为的元素custom_field,其中有一个column_name具有某个值(例如bar)的子元素,然后找到该子元素的兄弟姐妹column_value并获得其值。现在,我在上使用XPath XMlDocument

string path = "//custom_fields/custom_field[column_name='" + key + "']";
XmlNode xNode = doc.SelectSingleNode(path);
if (xNode != null)
{
    XmlNode v = xNode.SelectSingleNode("column_value");
    val.SetValue(v.InnerText);
}
Run Code Online (Sandbox Code Playgroud)

key我要查找的字段的名称在哪里。

但是我想在上使用新的LINQ to XML语法来做到这一点XDocument。我的想法是,我将大部分旧式XPath解析移至LINQ方法。也许这不是一个好主意,但是在这种情况下,如果我能使它工作,那么我相信我对LINQ会有一个更好的了解,并且能够清理很多复杂的代码。

Jef*_*ado 5

您始终可以在LINQ to XML中使用XPath。仅包括System.Xml.XPath名称空间。

var xpath = $"//custom_fields/custom_field[column_name='{key}']/column_value";
var columnValue = doc.XPathSelectElement(xpath);
if (columnValue != null)
{
    val.SetValue((int)columnValue);
}
Run Code Online (Sandbox Code Playgroud)

否则,对于等效的LINQ to XML查询:

var columnValue = doc.Descendants("custom_fields")
    .Elements("custom_field")
    .Where(cf => (string)cf.Element("column_name") == key) // assuming `key` is a string
    .Elements("column_value")
    .SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)