2

I have the following XPATH line:

//det[@nItem="1"]/prod/cProd

That successfully selects the desired node using XPath Visualizer, where it identifies automatically the namespace, and you define in which namespace you want to select.

When I specify the namespace in C# with the following XPATH code:

"http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd"

it gives me an XPathException:

An unhandled exception of type 'System.Xml.XPath.XPathException' occurred in System.Xml.dll Additional information: 'http://www.portalfiscal.inf.br/nfe//det[@nItem="1"]/prod/cProd' has an invalid qualified name.

(as you can see, it's not any escape character or anything, since it gives me what i've tried to reach in the exception)

How do I properly select this node providing that I know the namespace with XPath ?

--[EDIT]-- The complete line where I try to read the node:

doc.XPathSelectElement("http://www.portalfiscal.inf.br/nfe//det[@nItem=\"1\"]/prod/cProd").Value;

And the XML with unnecessary things cut out:

<?xml version="1.0" encoding="utf-8"?>
<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
<idLote>1</idLote>
<NFe>
<infNFe versao="1.10" Id="NFe31100118583682000178550010000077778397333128">
<det nItem="1">
<prod>
<cProd>111</cProd>
</prod>
</det>
</infNFe>
</NFe>
</enviNFe>

(The unnecessary things cut out should not be a problem, since XPath Visualizer brought me the node with no problems at all)

1
  • 1
    Thanks for the updates - a note: when posting code and/or XML, you should always highlight those lines in the editor, and then press on the "code" button (101 010) on the editor toolbar to format them nicely and get syntax highlighting going etc. Otherwise, your XML will remain mostly hidden..... Commented Apr 9, 2010 at 13:19

1 Answer 1

6

Since you're not showing us neither the XML document, nor the C# code you have, I can only guess what you're doing....

OK, seems you're using Linq-to-XML, so then use this code snippet here:

// Create and load XML reader
XmlReader reader = XmlReader.Create(new FileStream(@"D.\test.xml", FileAccess.Read));

// get the root element    
XElement root = XElement.Load(reader);


// create instance of XML namespace manager
XmlNamespaceManager nsmgr = new XmlNamespaceManager(reader.NameTable);

// add your namespace to the manager and give it a prefix
nsmgr.AddNamespace("ns", "http://www.portalfiscal.inf.br/nfe");

XElement node = root.XPathSelectElement("//ns:det[@nItem="1"]/ns:prod/ns:cProd", nsmgr);
.......

Something along those lines. You basically have to create a XML namespace of some sort, give it a prefix, and then use that prefix in your XPath expression - not the whole namespace - just the prefix.

Sign up to request clarification or add additional context in comments.

4 Comments

If you are not worried about performance you can select nodes by ignoring the namespace "//*[local-name()='det' and @*[local-name()='nItem']=1]/*[local-name()='prod']/*[local-name()='cProd']"
I've seen namespaces being used in the start of the xpath (like my non-working example) is there a way to put it IN the xpath syntax ?
@MarceloRamires: not to my knowledge, no - as far as I know, you have to create a prefix for the XML namespace and use it that way. I've never seen the full namespace used directly in the XPath
There are other problems with using local-name() besides performance. The most significant one is simply what it's doing: ignoring namespaces. Whenever you ignore namespaces, you run the risk of selecting nodes that are in a different namespace but happen to have the same local name as what you're looking for. That's bad.

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.