2

I have this XML code

<diffgr:diffgram xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1' FID='004'>
<Data>
   <users name='peter' UID='10003' diffgr:hasChanges='modified'/>
</Data>
</diffgr:diffgram>

I can get the name attribute by doing:

SelectSingleNode("/*/Data/*/@name");

and then print the value of that name. But I want the value of the attribute diffgr:hasChanges

I tried to do similar

SelectSingleNode("/*/Data/*/@diffgr:hasChanges");

But when trying to print the value, I get error saying

    Unhandled Exception:
System.Xml.XPath.XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
  at MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () <0x41689000 + 0x0003f> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Evaluate (System.Xml.XPath.XPathExpression expr, System.Xml.XPath.XPathNodeIterator context) <0x41688e20 + 0x0007b> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Evaluate (System.Xml.XPath.XPathExpression expr) <0x41688df0 + 0x0001a> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Select (System.Xml.XPath.XPathExpression expr) <0x41688d70 + 0x0001b> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Select (System.String xpath) <0x41684000 + 0x00026> in <filename unknown>:0 
  at System.Xml.XmlNode.SelectNodes (System.String xpath) <0x416839a0 + 0x00038> in <filename unknown>:0 
  at System.Xml.XmlNode.SelectSingleNode (System.String xpath) <0x41683950 + 0x00017> in <filename unknown>:0 
  at isoTopix.MyTest.Main (System.String[] args) [0x00018] in /home/tito/isoTopixSecurity/isoCode/console/tito.cs:28 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Xml.XPath.XPathException: Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.
  at MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () <0x41689000 + 0x0003f> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Evaluate (System.Xml.XPath.XPathExpression expr, System.Xml.XPath.XPathNodeIterator context) <0x41688e20 + 0x0007b> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Evaluate (System.Xml.XPath.XPathExpression expr) <0x41688df0 + 0x0001a> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Select (System.Xml.XPath.XPathExpression expr) <0x41688d70 + 0x0001b> in <filename unknown>:0 
  at System.Xml.XPath.XPathNavigator.Select (System.String xpath) <0x41684000 + 0x00026> in <filename unknown>:0 
  at System.Xml.XmlNode.SelectNodes (System.String xpath) <0x416839a0 + 0x00038> in <filename unknown>:0 
  at System.Xml.XmlNode.SelectSingleNode (System.String xpath) <0x41683950 + 0x00017> in <filename unknown>:0 

I guess I need some escaping cus of the colon. But how do I do this?

1
  • Sorry, this is not the real xml. For security reasons, I made this up, it looks very much like the real one. The issue is not that it's not well-formed, if it was, I would not be able to select the other attributes either. The issue lies in selecting this kind of attribute diffgr:hasChanges='modified (cus of the colon I think) Commented Feb 5, 2018 at 14:30

1 Answer 1

1

As said in the error message

Namespace Manager or XsltContext needed.

You need to set a namespace for diffgr. Otherwise the expression for the attribute @diffgr:hasChanges will not match.

In XSLT you'd add the namespace to the root element

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1'>

In C# with XmlReader you can add a namespace like this:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(reader.NameTable);
nsmgr.AddNamespace("diffgr", "urn:schemas-microsoft-com:xml-diffgram-v1");    
XElement node = root.XPathSelectElement("/*/Data/*/@diffgr:hasChanges", nsmgr);

If this doesn't help, try this SO answer: Namespace Manager or XsltContext needed.

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

1 Comment

Another way, easier and better in my case, I found out, that I can do this: SelectSingleNode("/*/Data/*/@*[name()='diffgr:hasChanges']"); By using name(), xpath won't look at the namespace, in this case.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.