【问题标题】:How to find XmlNodes based on a child elements name and value如何根据子元素名称和值查找 XmlNode
【发布时间】:2016-02-19 20:09:01
【问题描述】:

我无法获得一个 XmlNodeList,其中有 1 个具有特定名称的孩子

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

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

我已经反序列化了顶级订单...现在我想找到 OrderWithParent 的列,其中 columnName="OrderParentId" == order.Id

这样检索的订单节点:

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

所以 atm 我使用 XmlDocument.. 我希望也使用 XDocument.. 但我无法找到其中任何一个的解决方案。非常感谢您的帮助!

【问题讨论】:

  • 您可以发布您的 XML 的有效示例吗?不一定要满,但足以测试。
  • 应该够了。唯一缺少的是顶部标签 我想选择所有 OrderWithParent 其中 columnName="OrderParentId" 列的值为 1 作为示例..跨度>
  • 缺少结束标签
  • 好的,已更新。现在有 3 个 OrderWithParent .. 所以如果我搜索 OrderParentId = 1 的那个 .. 我想从 3 个中得到 2 个;)

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


【解决方案1】:

假设order.Id 表示您未显示的预定义变量orderId 属性,则以下XPath 应返回目标item 元素:

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

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

var xpath = String.Format("//item[@table='OrderWithParent' and column[@columnName='OrderWithParentId'] = {0}]", order.Id);

另一个假设是,order.Id 值始终是数字。否则,您需要在 XPath 中用引号将值括起来,即在上面的 sn-p 中,将 {order.Id} 替换为 '{order.Id}' 或将 {0} 替换为 '{0}'

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • SelectNodes 的行,我用来选择 Orders 的那一行...这些很简单,因为我想要所有这些...但现在我想选择所有 OrderWithParent 的列,它们的 columnName= “OrderParentId”具有特定值。您发布的行将获得所有这些,而不是在 OrderParentId 上过滤
    【解决方案3】:

    试试这个

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      相关资源
      最近更新 更多