We are processing an XML file format where the vendor changed the namespace of the elements between versions, but many of the elements and attributes are the same and we could re-use our small subset of XPath queries.
The old format looked like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
... interesting stuff here ...
</PropertyGroup>
</Project>
while the new format looks like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
... interesting stuff here ...
</PropertyGroup>
</Project>
Our existing code does this:
XmlDocument doc = new XmlDocument();
doc.Load(inputFile);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("ms", "http://schemas.microsoft.com/developer/msbuild/2003");
...
foreach (XmlNode xn in doc.DocumentElement.SelectNodes("//ms:PropertyGroup", nsMgr)) ...
Now, for the new format, I can do the following, and it still works with my VS2022 but I am not sure whether this is "legal", adding an empty namespace via AddNamespace
?:
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlElement root = doc.DocumentElement;
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
if (!String.IsNullOrEmpty(root.NamespaceURI))
{
nsMgr.AddNamespace("ms", root.NamespaceURI);
} else {
// <Project Sdk="Microsoft.NET.Sdk">
// Just register ms: as empty
nsMgr.AddNamespace("ms", "");
}
Use of an empty string in a namespace declaration has a specific meaning in XML Namespaces 1.1: it turns it into an "undeclaration", so within its scope, the prefix "em" is not associated with any URI. But ... XML Namespaces 1.0 explicitly says (§2.2): The empty string, though it is a legal URI reference, cannot be used as a namespace name.
... but this is from the XML side of things, not the parser / parser helper side.
Q: Using C# System.Xml.*
, how do I XPath-query two different XML files that have the same structure, but one declares a toplevel namespace and the other does not?