带有命名空间的XPath选择节点

Pet*_*ter 64 xml vb.net xpath xml-namespaces

它是一个.vbproj,看起来像这样

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ProjectGuid>15a7ee82-9020-4fda-a7fb-85a61664692d</ProjectGuid>
Run Code Online (Sandbox Code Playgroud)

我想得到的只是ProjectGuid,但是当命名空间存在时它不起作用......

 Dim xmlDoc As New XmlDocument()
 Dim filePath As String = Path.Combine(mDirectory, name + "\" + name + ".vbproj")
 xmlDoc.Load(filePath)
 Dim value As Object = xmlDoc.SelectNodes("/Project/PropertyGroup/ProjectGuid")
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能解决这个问题?

ann*_*ata 63

我可能倾向于使用Bartek的*命名空间解决方案,但一般的xpath解决方案是:

//*[local-name()='ProjectGuid']

**自从Bartek的回答消失后,我推荐Teun(实际上更彻底)*

  • 好的捕获,这是一个不要声明无聊和昂贵的命名空间的好方法 (3认同)

Teu*_*n D 44

这样做(IMHO)的最佳方法是创建命名空间管理器.这可以用于调用SelectNodes来指示哪些名称空间URL连接到哪些前缀.我通常设置一个静态属性,返回一个像这样的适当实例(它是C#,你必须翻译):

private static XmlNamespaceManager _nsMgr;
public static XmlNamespaceManager NsMgr
{
  get
  {
    if (_nsMgr == null)
    {
      _nsMgr = new XmlNamespaceManager(new NameTable());
      _nsMgr.AddNamespace("msb", "http://schemas.microsoft.com/developer/msbuild/2003");
    }
    return _nsMgr;
  }
}
Run Code Online (Sandbox Code Playgroud)

我这里只包含一个命名空间,但你可以有多个命名空间.然后你可以从这样的文件中选择:

Dim value As Object = xmlDoc.SelectNodes("/msb:Project/msb:PropertyGroup/msb:ProjectGuid", NsMgr)
Run Code Online (Sandbox Code Playgroud)

请注意,所有元素都在指定的命名空间中.

  • 令人惊讶的是,从长远来看,它可以节省多少时间来正确使用名称空间. (2认同)

Tom*_*lak 27

这个问题已经 几次 .

要么使用与命名空间无关的XPath表达式(不推荐它的笨拙和可能的误报匹配 - <msb:ProjectGuid>并且<foo:ProjectGuid>对于此表达式是相同的):

//*[local-name() = 'ProjectGuid']

或者您做正确的事情并使用a XmlNamespaceManager来注册名称空间URI,以便您可以在XPath中包含名称空间前缀:

Dim xmlDoc As New XmlDocument()
xmlDoc.Load(Path.Combine(mDirectory, name, name + ".vbproj"))

Dim nsmgr As New XmlNamespaceManager(xmlDoc.NameTable)
nsmgr.AddNamespace("msb", "http://schemas.microsoft.com/developer/msbuild/2003")

Dim xpath As String = "/msb:Project/msb:PropertyGroup/msb:ProjectGuid"
Dim value As Object = xmlDoc.SelectNodes(xpath, nsmgr)
Run Code Online (Sandbox Code Playgroud)