【问题标题】:LINQ to XML equivalent of XPathLINQ to XML 等效于 XPath
【发布时间】:2011-02-18 23:55:16
【问题描述】:

我有解析 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...

我想找到名为custom_field 的元素,该元素有一个名为column_name 且具有特定值的子元素(例如bar),然后找到该子元素的兄弟column_value 并获取其值。现在我在 XMlDocument 上使用 XPath 来执行此操作:

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

key 是我要查找的字段的名称。

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

【问题讨论】:

标签: c# xpath linq-to-xml


【解决方案1】:

您始终可以在 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);
}

否则对于等效的 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();

【讨论】:

  • 我认为最佳答案是 XPath 注入问题。
【解决方案2】:

您的 XQuery 表达式

//custom_fields/custom_field[column_name='key']

选择custom_fields 元素中的所有custom_field 元素,其中column_key 子元素的值等于"key"。您希望返回单个元素并选择 column_value 子元素的值。

您可以使用 LINQ to XML 如下表示:

var doc = XDocument.Load(...);

var query = from fields in doc.Descendants("custom_fields")
            from field in fields.Elements("custom_field")
            where (string)field.Element("column_name") == "key"
            select (int)field.Element("column_value");

int result = query.Single();

【讨论】:

    【解决方案3】:

    我想找到名为 具有子元素的 custom_field 称为 column_name 具有一定的 值(例如“bar”,然后 找到那个孩子的兄弟姐妹叫 column_value 并获取它的值。

    用途:

    /custom_fields/custom_field[column_name = 'bar']/column_value
    

    【讨论】:

    • 使用 XPathSelectElement
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多