Im having trouble getting a XmlNodeList where there is 1 child with a specific name that
<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>
So thats my basic xml layout...
Ive deserialized the top Orders... and now i wanna find the OrderWithParent's where their column with columnName="OrderParentId" == order.Id
the order nodes where retrieved like this:
var orders = root.SelectNodes("/tables/table[@tableName='Orders']/item[@table='Orders']");
So atm im using an XmlDocument.. im hope to using XDocument aswell.. but i havent been able to find a solution with either of them. Help is much appreciated!
Assuming that order.Id
means Id
property of a predefined variable order
which you didn't show, the following XPath should return the target item
element :
var xpath = $"//item[@table='OrderWithParent' and column[@columnName='OrderWithParentId'] = {order.Id}]";
For older C# version where string interpolation $
is not supported :
var xpath = String.Format("//item[@table='OrderWithParent' and column[@columnName='OrderWithParentId'] = {0}]", order.Id);
Another assumption is, that order.Id
value is always number. Otherwise you'll need to wrap the value with quotes in the XPath i.e in the above snippet, replace {order.Id}
with '{order.Id}'
or {0}
with '{0}'
.
If you switch to using XDocument
, you can still execute the same XPath expression through XPathSelectElements()
, XPathSelectElement()
, or XPathEvaluate()
methods.
I think your searching for the wrong node in your syntax. Try this, see if it helps:
var orders = root.SelectNodes("/tables/table[@tableName='OrderWithParent']/item[@table='OrderWithParent']");
this assumes I'm not misunderstanding the question though.
Try this
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();
}
}
}