tags:

views:

429

answers:

2

I'm working on Open XML document format for excel sheets.

var nodeList = WorksheetXml.SelectNodes(@"//c[child::f]");

it should return all rows with formulas, but it doesn't return anything. The same xml on Oxygen Editor, when applied the same xpath expression, returns all of them.

I am copying WorksheetXml inner xml to assure the content is the same... do you know why C# is not working the expected way?


EDIT: Namespace issue

I've put this:

var manager = new XmlNamespaceManager(WorksheetXml.NameTable);
manager.AddNamespace(string.Empty, @"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
manager.AddNamespace("r", @"http://schemas.openxmlformats.org/officeDocument/2006/relationships");

var nodeList = WorksheetXml.SelectNodes(@"//c[child::f]", manager);

and it didn't work, I think it is not a namespace problem.

+3  A: 

Is it possible that Oxygen Editor is handling namespaces differently? My guess is that the c element is in a namespace, but you aren't specifying one.

See this very similar question for sample code - and if that's not the problem, please post more details.

EDIT: The code you've posted still doesn't use a namespace in the XPath. Try this:

var manager = new XmlNamespaceManager(WorksheetXml.NameTable);
manager.AddNamespace("n", 
    "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
manager.AddNamespace("r",  
    "http://schemas.openxmlformats.org/officeDocument/2006/relationships");

var nodeList = WorksheetXml.SelectNodes("//n:c[child::n:f]", manager);

(I don't know which namespace the c and f elements are meant to be in - adjust appropriately.)

(Note that there's no need to use a verbatim string literal when you have no backslashes and the string is on one line.)

Jon Skeet
c element is from the default namespace. I've added a namespacemgr and it still doesn't return anything =/
Victor Rodrigues
And which is the default namespace here? I'm sure you don't mean the empty namespace. Do you mean main or relationships? See my edit.
Jon Skeet
I've resolved this issue without XPath, since it was not working and I had to deliver the code last week.Creating this 'n' -even if in xml this is the "empty" namespace, and c is just <c ...>...</c>- and handling c as n:c would help?
Victor Rodrigues
Yes, because it's not *actually* in the empty namespace, it's in the default namespace for that level of the document, as specified by an ancestor's xmlns="..." attribute.
Jon Skeet
A: 

You did not specify OpenXML namespace for the nodes in your XPath expression. All stock .NET XPath APIs that I know of do not inherit any namespaces from document context - so if you do not explicitly specify it, and don't use any prefixes in XPath expression, it is treated as empty namespace.

Assuming that this is a call to XmlNode.SelectNode, you need the 2-argument overload where the second argument is XmlNamespaceManager.

Pavel Minaev
I've changed the calling, passing manager as a parameter, and it still doesn't work =/
Victor Rodrigues
It doesn't work because in XPath, an element without a prefix is _always_ in the empty namespace (i.e. with no URI), regardless of what you do in XmlNamespaceManager. See http://www.w3.org/TR/xpath#node-tests:A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. ... the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). You _have_ to use a prefix in your XPath for it to work.
Pavel Minaev