XPath和Powershell-默认命名空间

7
我有以下的PowerShell函数:
function getProjReferences([string] $projFile) {

    # Returns nothing
    $Namespace = @{ ns = "http://schemas.microsoft.com/developer/msbuild/2003"; };
    $Xml = Select-Xml -Path $projFile -Namespace $Namespace -XPath "//ns:Project/ItemGroup/Reference"

    # Returns nothing
    [xml] $xml = Get-Content -Path $projFile
    [System.Xml.XmlNamespaceManager] $nsMgr = New-Object -TypeName System.Xml.XmlNamespaceManager($xml.NameTable)
    $nsMgr.AddNamespace("ns", "http://schemas.microsoft.com/developer/msbuild/2003");
    [XmlNode] $nodes = $xml.SelectNodes("/ns:Project/ItemGroup/Reference", $nsMgr);
}

尽管XPath查询是完全有效的,但两次尝试都没有返回任何内容。我已经尝试在xml中删除默认命名空间xmlns="http://schemas.microsoft.com/developer/msbuild/2003",这样可以正常工作。

我知道我必须将默认命名空间映射到URI,并使用此映射来查询XML,但似乎无法使其工作。

如何使用默认命名空间查询XML?我还没有在Google上找到任何可用的信息。

更新

工作代码:

function getProjReferences([string] $projFile) {

    [xml] $xml = Get-Content -Path $projFile
    [System.Xml.XmlNamespaceManager] $nsMgr = New-Object -TypeName System.Xml.XmlNamespaceManager($xml.NameTable)
    $nsMgr.AddNamespace("ns", "http://schemas.microsoft.com/developer/msbuild/2003");
    [XmlNode] $nodes = $xml.SelectNodes("/ns:Project/ns:ItemGroup/ns:Reference", $nsMgr);
}

请展示输入的XML文档。 - Mathias Müller
1个回答

5

如果没有查看实际的XML文档(或其代表性样本),我无法百分之百确定。无论如何,这通常是由于xpath中缺少命名空间前缀引起的。

请注意,在默认命名空间的情况下,不仅声明默认命名空间的元素,而且其所有后代元素都被视为处于同一命名空间*。我建议尝试以下xpath:

/ns:Project/ns:ItemGroup/ns:Reference

*:除了在后代元素中明确使用前缀或在更局部的范围内声明其他默认命名空间之外。


该句话涉及到IT技术中的XML命名空间,意思是在使用XML命名空间时,如果在后代元素中没有明确使用前缀或在更局部的范围内声明其他默认命名空间,则会默认使用父级元素的命名空间。

谢谢,你说得对,我需要在每个元素前加上命名空间前缀。这似乎有点奇怪,因为它是“默认”命名空间。 - user1359448
不需要使用NamespaceManager或为每个元素使用前缀,只需使用"/Project/ItemGroup/Reference"和$Ns = @{"ns"="http://schemas.microsoft.com/developer/msbuild/2003"} - 至少在PowerShell版本5.1中。 - PeterXX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接