LINQ to XML 相当于 XPath

发布于 2024-10-17 21:20:20 字数 1425 浏览 3 评论 0原文

我有解析 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 总体有更好的理解,并且能够清理很多复杂的代码。

I have code which parses XML that looks like this:

<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...

I want to find the element called custom_field which has a child element called column_name with a certain value (for example bar), and then find that child's sibling called column_value and get its value. Right now I use XPath on an XMlDocument to do this:

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

Where key is the name of the field I am looking for.

But I want to do this using the new LINQ to XML syntax on an XDocument. My thinking is that I will move much of my old-style XPath parsing to the LINQ methods. Maybe it's not a good idea, but this is a case where if I can get it to work, then I believe I will have a much better understanding of LINQ in general, and will be able to clean up a lot of complex code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不再让梦枯萎 2024-10-24 21:20:20

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

You can always use XPath within LINQ to XML. Just include the System.Xml.XPath namespace.

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

Otherwise for the equivalent LINQ to XML query:

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();
寄风 2024-10-24 21:20:20

您的 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();

Your XQuery expression

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

selects all custom_field elements in custom_fields elements where the value of the column_key child element equals "key". You expect a single element to be returned and select the value of the column_value child element.

You can express this using LINQ to XML as follows:

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();
我们只是彼此的过ke 2024-10-24 21:20:20

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

使用:

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

I want to find the element called
custom_field which has a child element
called column_name with a certain
value (for example "bar", and then
find that child's sibling called
column_value and get its value.

Use:

/custom_fields/custom_field[column_name = 'bar']/column_value
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文