How to Use Xpath with Xdocument

how to use XPath with XDocument?

If you have XDocument it is easier to use LINQ-to-XML:

var document = XDocument.Load(fileName);
var name = document.Descendants(XName.Get("Name", @"http://demo.com/2011/demo-schema")).First().Value;

If you are sure that XPath is the only solution you need:

using System.Xml.XPath;

var document = XDocument.Load(fileName);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("empty", "http://demo.com/2011/demo-schema");
var name = document.XPathSelectElement("/empty:Report/empty:ReportInfo/empty:Name", namespaceManager).Value;

How can I perform an XPath selection on an XElement that was extracted from a larger XDocument?

Unless you make a copy or clone of the XML structure, you can simply use a path relative to the context node like

b.XPathSelectSelectElement("C")

This should return the <C /> element.

The / axis always selects the document node of the XML.

How to write xpath for this XDocument?

You are missing the 'data' element. Try

xdDiffData.XPathSelectElement("//tags/data[@mode='add']") != null &&        xdDiffData.XPathSelectElement("//tags/data[@mode='delete']") != null

How can I query an XDocument with a 'path'?

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;

XDocument how to search by xpath

Your XML has default namespace here :

<asmv1:assembly 
......
xmlns="urn:schemas-microsoft-com:asm.v2"
......>

Therefore, all XML element without prefix considered in default namespace. You need to add prefix that point to default namespace URI, and use it in XPath :

var nsmgr = new XmlNamespaceManager(new NameTable());
nsmgr.AddNamespace("asmv1", "urn:schemas-microsoft-com:asm.v1");
nsmgr.AddNamespace("d", "urn:schemas-microsoft-com:asm.v2");
xpath = "//asmv1:assembly/d:dependency/d:dependentAssembly/d:assemblyIdentity[@name='ImageListView']";
XElement ele = doc.XPathSelectElement(xpath, nsmgr);
ele.Remove();

UPDATE :

fixed the XPath slightly. You need to use @ to point to attribute : ... [@name='ImageListView']

Ignore CData when using XPath with XDocument

Please try the following conceptual example.

c#

void Main()
{
string elementName = "CarName";

XElement xelem = XElement.Parse("<CarName><![CDATA[XXX Jan]]></CarName>");

XElement x = xelem.DescendantsAndSelf(elementName).FirstOrDefault();
Console.WriteLine(x.Value);
}

Output

XXX Jan

Write XDocument's attribute value via XPath

It looks like XPathEvaluate() would solve your problem:

using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;

foreach (XAttribute attr in ((IEnumerable)
yourDocument.XPathEvaluate(yourXPath)).OfType<XAttribute>()) {
attr.Value = yourValue;
}

Weirdness with XDocument, XPath and namespaces

In addition to the correct remark by @Mads-Hansen, you have the typical problem of not defining a (nonempty) prefix for one of the namespaces.

Remember: XPath considers any unprefixed name to be in "no namespace".

Therefore this is wrong:

Source.XPathSelectElement("//kmsg", oManager)

This XPath expression wants to select all kmsg elements that are in "no namespace" and it correctly selects nothing, because any kmsg elements in the provided XML document are in the "http://url1" namespace, and not in "no namespace".

To do it correctly:

oManager.AddNamespace("xxx", "http://url1");      
Source.XPathSelectElement("//xxx:kmsg", oManager)


Related Topics



Leave a reply



Submit