(It's been a while since I blogged about anything, so I thought I'd write about this while my coffee kicks in on a Monday morning.)
An issue which comes up quite often is people seeing this error when they try to use XML actions in FinalBuilder or Automise:
XPath returned no node : /Project/Import
The reason is because of the way MSXML deals with document namespaces. If your XML file uses XML namespaces (and most do), then you need to tweak the action slightly.
I'm not going to go into XML Namespaces in detail. There are better places to learn about them. I'll just show you an example:
Say you have a Visual Studio 2005 .csproj file (which is really just an XML file wearing a funny hat.) You want to iterate over all of the imported project names with an XML Node Iterator action. If you try to use the XPath /Project/Import, then you'll see the error I showed above.
Here's the first line of the .csproj file:
This means the document has a default XML Namespace, which is "http://schemas.microsoft.com/blahblahblah". This is why MSXML can't follow the XPath properly.
To fix this, open the XML action and navigate to the "MSXML Parser" page.
Turn on the "Automatically use namespace prefixes..." checkbox, and type a letter in the field for the default Namespace. I used "x" in the screenshot shown above.
Now change your XPath from /Project/Import to:
It works! Namespace prefix "x" now refers to the default namespace in the document.
- There is a way to specify the namespace URI as part of the XPath, without using this prefix feature, but the resulting XPaths are enormous and hard for humans to read.
- If you have namespace prefixes defined as attributes in the document root node, ie s:xmlns="http://www.myfunkyurl.com/namespace", then turning on this option will let you use the prefixes in your XPath.
- This is the best solution we've come up with so far. We're planning to revisit this in future and (hopefully) make it all automatic without any manual configuration or custom prefixes.