如何根据子元素名称和值查找XmlNodes

时间:2016-02-19 20:09:02

标签: c# xml xpath linq-to-xml xmldocument

我无法获取XmlNodeList,其中有1个具有特定名称的子项

table

那就是我的基本xml布局......

我已经对顶级订单进行了反序列化...现在我想找到OrderWithParent,其列名为columnName =" OrderParentId" == order.Id

这样检索的订单节点:

<tables>
  <table tableName="Orders">
    <item table="Orders">
      ...
   </item>
    <item table="Orders">
      ...
   </item>
  </table>
  <table tableName="OrderWithParent">
    <item table="OrderWithParent">
      <column columnName="OrderWithParentId"><![CDATA[156]]></column>
      <column columnName="OrderParentId"><![CDATA[1]]></column>
      ...
   </item>
    <item table="OrderWithParent">
      <column columnName="OrderWithParentId"><![CDATA[156]]></column>
      <column columnName="OrderParentId"><![CDATA[1]]></column>
      ...
   </item>
    <item table="OrderWithParent">
      <column columnName="OrderWithParentId"><![CDATA[156]]></column>
      <column columnName="OrderParentId"><![CDATA[2]]></column>
      ...
   </item>
  </table>
</tables>

所以我现在使用XmlDocument ..我希望使用XDocument以及..但我还没有能够找到任何一个解决方案。非常感谢帮助!

3 个答案:

答案 0 :(得分:1)

假设/etc/hosts表示您未显示的预定义变量order.Id的{​​{1}}属性,则以下XPath应返回目标Id元素:< / p>

order

对于不支持字符串插值item的旧版C#版本:

var xpath = $"//item[@table='OrderWithParent' and column[@columnName='OrderWithParentId'] = {order.Id}]";

另一个假设是,$值始终为数字。否则,您需要在XPath中使用引号包装值,即在上面的代码段中,将var xpath = String.Format("//item[@table='OrderWithParent' and column[@columnName='OrderWithParentId'] = {0}]", order.Id); 替换为order.Id{order.Id}替换为'{order.Id}'

如果您切换到使用{0},您仍然可以通过XPathSelectElements()XPathSelectElement()XPathEvaluate()方法执行相同的XPath表达式。

答案 1 :(得分:0)

我认为您在语法中搜索错误的节点。试试这个,看看是否有帮助:

var orders = root.SelectNodes("/tables/table[@tableName='OrderWithParent']/item[@table='OrderWithParent']");

这假设我并没有误解这个问题。

答案 2 :(得分:0)

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                    "<tables>" +
                      "<table tableName=\"Orders\">" +
                        "<item table=\"Orders\">" +
                          "..." +
                        "</item>" +
                        "<item table=\"Orders\">" +
                          "..." +
                        "</item>" +
                      "</table>" +
                      "<table tableName=\"OrderWithParent\">" +
                        "<item table=\"OrderWithParent\">" +
                          "<column columnName=\"OrderWithParentId\"><![CDATA[156]]></column>" +
                          "<column columnName=\"OrderParentId\"><![CDATA[1]]></column>" +
                          "..." +
                        "</item>" +
                        "<item table=\"OrderWithParent\">" +
                          "<column columnName=\"OrderWithParentId\"><![CDATA[156]]></column>" +
                          "<column columnName=\"OrderParentId\"><![CDATA[1]]></column>" +
                          "..." +
                        "</item>" +
                        "<item table=\"OrderWithParent\">" +
                          "<column columnName=\"OrderWithParentId\"><![CDATA[156]]></column>" +
                          "<column columnName=\"OrderParentId\"><![CDATA[2]]></column>" +
                          "..." +
                        "</item>" +
                      "</table>" +
                    "</tables>";

            XDocument doc = XDocument.Parse(xml);

            XElement[] results = doc.Descendants("table").Elements("item")
                .Where(y => ((string)y.Attribute("table") == "OrderWithParent") &&
                    (y.Elements("column").Where(z => 
                       (z.Attribute("columnName") != null) &&
                       (z.Attribute("columnName").Value == "OrderParentId") &&
                       (z.Value  == "1")
                       )).Any()
                    )
                .ToArray();
        }
    }
}