Namespaces, Why Does It Always Have To Be Namespaces?
I’ll be honest, I LOATHE namespaces in XML. I haven’t seen a case where I needed to use them to differentiate between identically-named elements in different contexts. So often, the document declares a namespace at the top and never overrides it. In that case, why use it?
Why do I hate it?
It breaks XPath navigation. Or, at least it breaks my rudimentary grasp of XPath. Someone sent a Lync topology builder file (it’s all 192.168.x.x and 10.x.x.x non-routable addresses, anyhow) with a simple question: how to get the IPAddress attribute value for <NetInterface> elements.
$xml.SelectNodes(“//NetInterface”) | Select-Object –Property IPAddress
But, nooooooooooooooooo…
Here are some of the answers that I’ve seen:
This is one that plays nice with namespaces. Notice that it’s not XPath.
$xml = [xml]"$(gc tbxml.xml)"
($xml | Select-Xml '(//wt:CentralSites)[1]/wt:CentralSite[2]/t:Location' -Namespace @{
wt = 'urn:schema:Microsoft.Rtc.Management.Deploy.WritableTopology.2008'
t = 'urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008'
}).Node
Here’s one that dispenses with namespaces and XPath and just uses the DOM (Document Object Model) to navigate the XML:
$xml = [xml](gc tbxml.xml)
$centralsite = $xml.TopologyBuilder.OriginalTopology.PartialTopology.CentralSites.CentralSite
| ? { $_.Name.InnerXml -eq "CentralSite1" }
if ($centralsite)
{
$centralsite.Clusters.Cluster.Machines.Machine.NetInterface |
Select-Object -Property @{
Name = "FQDN";
Expression = { $_.ParentNode.Fqdn; }
},@{
Name = "IPAddress";
Expression = { $_.IPAddress; }
}
}
My contribution to the ruckus at least uses XPath, albeit inefficiently:
$xml = (Get-Content -Path YaddaYadda.xml) -as [xml];
$objects = $xml.SelectNodes("//*[name()='NetInterface']") |
Select-Object @{
n = 'MachineFQDN'; e = { $_.ParentNode.Fqdn.Tolower(); }
}, @{
n = 'ClusterFQDN'; e = { $_.ParentNode.ParentNode.ParentNode.Fqdn.ToLower(); }
}, IPAddress, InterfaceNumber, InterfaceSide;