I would like to query an XDocument
object for a given path, (e.g. "/path/to/element/I/want") but I don't know how to proceed.
How can I query an XDocument with a 'path'?
possible duplicate of how to use XPath with XDocument? –
Horary
You can see an example selecting different paths, with / without namespace definitions, etc. here: https://mcmap.net/q/73134/-how-do-i-get-an-ixmlnamespaceresolver. –
Microbalance
Something similar to this might work:
var path = "/path/to/element/I/want";
var route = path.Split(new []{'/'}, StringSplitOptions.RemoveEmptyEntries);
XElement result = null;
foreach (var node in route)
{
if (result == null)
{
result = _xmlDocument.Element(node);
}
else
{
result = result.Element(node);
}
}
return result;
RemoveEmptyEntries
is not a good idea, //
has a specific meaning in XPath and it's to search all descendants. –
Affiliate and the condition
result==null
will provide odd results too. –
Moulding tried to edit. Nothing wrong there with the Split given that has nothing to do with XPath –
Moulding
You can use methods from System.Xml.XPath.Extensions
to do this.
For example, if you want to select a single element, you would use XPathSelectElement()
:
var element = doc.XPathSelectElement("/path/to/element/I/want");
The queries don't have to be simple paths like what you described, they use the XPath language.
In 4.5, use System.Xml.XPath. –
Armourer
@Armourer Isn't that exactly what I suggested? And the
System.Xml.XPath
namespace certainly isn't new in .Net 4.5. –
Affiliate Even though this is a somewhat older post, it should be noted that LINQ-to-XML
can be used as an alternative to System.XML.XPath
to find elements based on a path within an XDocument
Example:
var results = x.Elements("path").Elements("to").Elements("element").Elements("I").Elements("want").FirstOrDefault();
Note: The LINQ to XML command may need to be altered to accommodate for the actual structure and/or cardinality of the XML.
This makes no sense. What is x ? If x is an XContainer then Elements is an IEnumerable of XElement and you cannot chain. –
Moulding
Similar to DaveDev but does work, if you do not want to use XPath.
public static class XElementExtensions
{
public static XElement GetStrictDescendant(this XContainer element, string path)
{
// todo guard against null path
var names = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if (names.Length == 0)
throw new ArgumentException("Empty path", nameof(path));
var result = element;
foreach (var name in names)
{
result = result.Element(name);
if (result == null)
{
return null;
}
}
return (XElement)result;
}
}
Something similar to this might work:
var path = "/path/to/element/I/want";
var route = path.Split(new []{'/'}, StringSplitOptions.RemoveEmptyEntries);
XElement result = null;
foreach (var node in route)
{
if (result == null)
{
result = _xmlDocument.Element(node);
}
else
{
result = result.Element(node);
}
}
return result;
RemoveEmptyEntries
is not a good idea, //
has a specific meaning in XPath and it's to search all descendants. –
Affiliate and the condition
result==null
will provide odd results too. –
Moulding tried to edit. Nothing wrong there with the Split given that has nothing to do with XPath –
Moulding
© 2022 - 2024 — McMap. All rights reserved.