如何根据 child 元素名称和值查找 XmlNodes
How to find XmlNodes based on a child elements name and value
我在获取 XmlNodeList 时遇到问题,其中有 1 个 child 具有特定名称
<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 的列,其中列名="OrderParentId" == order.Id
这样检索的订单节点:
var orders = root.SelectNodes("/tables/table[@tableName='Orders']/item[@table='Orders']");
所以 atm 我正在使用 XmlDocument.. 我希望也使用 XDocument.. 但我还没有找到解决方案。非常感谢您的帮助!
我认为您在语法中搜索了错误的节点。试试这个,看看是否有帮助:
var orders = root.SelectNodes("/tables/table[@tableName='OrderWithParent']/item[@table='OrderWithParent']");
这是假设我没有误解问题。
假设 order.Id
表示预定义变量 order
的 Id
属性 而您未显示,则以下 XPath 应该 return 目标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 中用引号将值括起来,即在上面的代码片段中,将 {order.Id}
替换为 '{order.Id}'
或将 {0}
替换为 '{0}'
.
如果您切换到使用 XDocument
,您仍然可以通过 XPathSelectElements()
, XPathSelectElement()
, or XPathEvaluate()
方法执行相同的 XPath 表达式。
试试这个
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();
}
}
}
我在获取 XmlNodeList 时遇到问题,其中有 1 个 child 具有特定名称
<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 的列,其中列名="OrderParentId" == order.Id
这样检索的订单节点:
var orders = root.SelectNodes("/tables/table[@tableName='Orders']/item[@table='Orders']");
所以 atm 我正在使用 XmlDocument.. 我希望也使用 XDocument.. 但我还没有找到解决方案。非常感谢您的帮助!
我认为您在语法中搜索了错误的节点。试试这个,看看是否有帮助:
var orders = root.SelectNodes("/tables/table[@tableName='OrderWithParent']/item[@table='OrderWithParent']");
这是假设我没有误解问题。
假设 order.Id
表示预定义变量 order
的 Id
属性 而您未显示,则以下 XPath 应该 return 目标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 中用引号将值括起来,即在上面的代码片段中,将 {order.Id}
替换为 '{order.Id}'
或将 {0}
替换为 '{0}'
.
如果您切换到使用 XDocument
,您仍然可以通过 XPathSelectElements()
, XPathSelectElement()
, or XPathEvaluate()
方法执行相同的 XPath 表达式。
试试这个
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();
}
}
}