2

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.
 }

2 Answers 2

1

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']
Sign up to request clarification or add additional context in comments.

6 Comments

I did provide a XmlNamespaceManger object as you will note above. I assumed that would handle the namespacing part but apparrantly not. However, even with your version my compiler still throws the same exception as if I am not producing an expression intended to return a result set or something.
It does if you include teh prefix in the Xpath as in. SelectNode("kfx:SomeNodeName/kfx:SomeChildName",SomeNameSpaceManager)
@Kirill Polishchuk I stripped out of the namespaces to simplify the learning curve (if you haven't noticed this is my very first time with XML or XPath for that matter). I can get the item I'm after if I construct my query like so: doc.XPathSelectElements("XMLRELEASE/KOFAXXML/BATCHCLASS/DOCUMENTS/DOCUMENT/DOCUMENTDATA/DOCUMENTFIELD[@NAME='Producer Name']") There has got to be a better way though, have to start from the root and work my way all the way down is ridiculous.
@MatthewCox, Try this one: //DOCUMENTFIELD[@NAME='Producer Name']
@Kirill Polishchuk That is a much cleaner approach. I must apoligize. My actual code is much different than the exmaple I posted, trying to condense it to make the problem easier to identify. However, I mostly coded the example code in the question from scratch and I just noticed that my actual code was performing my searches from the original XML root node ... no wonder many of these attempts where failing. The help was much appreciated
|
1

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']

2 Comments

A step in the right direction (no more exception). However, apparently my query is incorrect as it produces no results. Any thoughts on the issue?
I personally never bother with the namespace manager. Have you tried removing it? Ohh just noticed I made a typeo btw... first namespace should be kfx not kxf, perhaps that is it. If that doesn't work strip all namespaces everywhere (source, ns-manager and query) and add them back in in steps. That eventually fixes it for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.