4

This a simplified version of a more complex XML that I need to manage with C#.

The problem is that when I try to access to a tag within a namespace, the XPATH does not work.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<s:Body xmlns:s=\"sssssss\"><s:SessionID>abcde</s:SessionID></s:Body>");
string xpath = "//*[local-name()='s:SessionID']";
Context.UserLogger.Info(xmlDoc.SelectSingleNode(xpath).InnerText);
//Object reference not set to an instance of an object

But the code works perfect without the colon on the tag.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<s:Body xmlns:s=\"sssssss\"><SessionID>abcde</SessionID></s:Body>");
string xpath = "//*[local-name()='SessionID']";
Context.UserLogger.Info(xmlDoc.SelectSingleNode(xpath).InnerText);
//abcde

I have ensured on a XPATH validator that the "//*[local-name()='s:SessionID']" works fine.

What I am missing?

Thanks in advance,

I have read info about XmlNamespaceManager but I would prefer to use "direct" paths. The XML is full of NameSpaces and it is dynamic, so its the structure changes quite often.

Andoxko
  • 1,021
  • 2
  • 12
  • 19
  • 1
    What do you mean by *""direct" paths"*? Your XML has namespaces, you need a namespace manager to use XPath on it. End of story. – Tomalak Sep 22 '17 at 09:33
  • @Tomalak with an online Xpath testes the "direct" path //*[local-name()='s:SessionID' works without any management of the namespace, why is that? – Andoxko Sep 22 '17 at 09:43
  • 1
    If that really works then it's because that particular online XPath tester is broken. `local-name()` would never return something like `'s:SessionID'`. – Tomalak Sep 22 '17 at 09:46
  • 1
    That being said, don't use `local-name()` in your XPath expressions. It's the wrong tool. There is nothing "direct" about it. If your XML has namespaces, use them properly. It's not hard, so there is no reason not to. – Tomalak Sep 22 '17 at 09:48
  • Ok, thank you for the answer :) I will mange the NS then. Just for you to know the XPath tester that I was using is https://codebeautify.org/Xpath-Tester – Andoxko Sep 22 '17 at 09:52
  • 1
    Jup, I just confirmed it - that XPath tester's `local-name()` function is broken. :) Try here, this one does the right thing: https://www.freeformatter.com/xpath-tester.html By the way, you can use Powershell's [`Select-Xml` cmdlet](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/select-xml?view=powershell-5.1) to quickly test XPath locally on your own machine. Just open the Powershell ISE and you have an quick and easy test-bed, even with access to all your local files. – Tomalak Sep 22 '17 at 09:58

1 Answers1

2

the function local-name() returns only the local part of a tag name that in your case is exactly SessionID that's why the expression '//*[local-name()='s:SessionID']' doesn't work (you need to compare qualified names not just strings) From your question it seems to me that your are interested in selecting the SessionsID elements, if it's so use just the xpath expression

string xpath = "//s:SessionID";

if it doesn't works then you probably need to bound the prefix s with the namespace uri s="sssssss" (take from your example)

gtosto
  • 1,381
  • 1
  • 14
  • 18