Matthew Cox
Matthew Cox

Reputation: 13672

Use XPath to find a node by name attribute value

I am trying to find a node by the name attribute value.

Here is a sample of the xml document:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE kfx:XMLRELEASE SYSTEM "K000A004.dtd">
<kfx:XMLRELEASE xmlns:kfx="http://www.kofax.com/dtd/">
  <kfx:KOFAXXML>
    <kfx:BATCHCLASS ID="00000008" NAME="CertficateOfLiability">
      <kfx:DOCUMENTS>
        <kfx:DOCUMENT DOCID="00000006" DOCUMENTCLASSNAME="COL">
          <kfx:DOCUMENTDATA>
            <kfx:DOCUMENTFIELD NAME="Producer Name" VALUE="Howalt+McDowell Insurance" />
           ...
           ....

Here is my attempted expression:

 var xml = XDocument.Load(new StreamReader("C:\\Users\\Matthew_cox\\Documents\\test.xml"));
 XNamespace ns = "http://www.kofax.com/dtd/";
 XmlNamespaceManager nsm = new XmlNamespaceManager(xml.CreateNavigator().NameTable);
 nsm.AddNamespace("kfx", ns.NamespaceName);

 var docs = xml.Descendants(ns + "DOCUMENT");
 foreach(var doc in docs)
 {
      doc.XPathSelectElement("/DOCUMENTDATA/DOCUMENTFIELD/[@name='Producer Name']", nsm); //this line produces this exception: Expression must evaluate to a node-set.
 }

Upvotes: 2

Views: 1852

Answers (2)

Kirill Polishchuk
Kirill Polishchuk

Reputation: 56162

XML is case-sensitive. In provided XML kfx:DOCUMENTFIELD has NAME attribute. Also your XPath doesn't have reference to namespace.

Try this XPath:

kfx:DOCUMENTDATA/kfx:DOCUMENTFIELD[@NAME = 'Producer Name']

Upvotes: 1

Captain Coder
Captain Coder

Reputation: 818

I see two things wrong.

First of all you are selecting starting with "/", this selects from the document root, so strip the leading slash.

Secondly the expression is a bit wierd. I would include the condition directly on DOCUMENTFIELD. (I am unsure if no expression on the node axis actually means something. As in is .../[..] equivalent to .../node()[..] or perhaps even .../*[..]?)

As Kirill notes, you should also watch the casing and namespaces, but this should solve c# complaining about expressions not evaluating to node sets:

kfx:DOCUMENTDATA/kfx:DOCUMENTFIELD[@NAME = 'Producer Name']

Upvotes: 1

Related Questions