views:

2266

answers:

5

Its a .vbproj and looks like this

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    <PropertyGroup>
        <ProjectGuid>15a7ee82-9020-4fda-a7fb-85a61664692d</ProjectGuid>

all i want to get is the ProjectGuid but it does not work when a namespace i there...

 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")

what can i do to fix this?

A: 

Why not use the // to ignore the namespace:

Dim value As Object = xmlDoc.SelectNodes("//ProjectGuid")

// acts as wild card to follow through everything between the root and the next node name specified(i.e ProjectGuid)

Lonzo
doesn't actually work - yes this says look for any ProjectGuids anywhere, but it still wants them within the default namespace
annakata
+4  A: 

I'd probably be inclined to go with Bartek's* namespace solution, but a general xpath solution is:

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

*since Bartek's answer has disappeared, I recommend Teun's (which is actually more thorough)

annakata
Agreed, although this becomes a real PITA when you have to go more than a couple of levels deep. It *does* work, though. :)
ZombieSheep
quite, which is why I'd go with Barteks - the only thing stopping me there is if I don't know the namespace beforehand or can't guarantee it, in which case I'd probably wash the entire doc first, but saying so will only get me stalker downvotes :)
annakata
Two problems with this: 1. It is ugly, 2. In this case it can be used but will provide wrong results if a 'ProjectGuid' element belongs to more than one namespace and we want the elements only from a single namespace. Solutions using the NamespaceManager are better.
Dimitre Novatchev
I'm surprised you haven't downvoted it already
annakata
I downvote something that's completely wrong, not something that's a solution, although not the best one
Dimitre Novatchev
+8  A: 

The best way to do things like this (IMHO) is to create a namespace manager. This can be used calling SelectNodes to indicate which namespace URLs are connected to which prefixes. I normally set up a static property that returns an adequate instance like this (it's C#, you'll have to translate):

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

I include only one namespace here, but you could have multiple. Then you can select from the document like this:

Dim value As Object = xmlDoc.SelectNodes("/msb:Project/msb:PropertyGroup/msb:ProjectGuid", NsMgr)

Note that all of the elements are in the specified namespace.

Teun D
you dont need to create a new XmlDocument to get a XmlNameTable. you can use nsMgr = new XmlNamespaceManager(new NameTable());
foson
Ah, thanks. I never found out how to do that. Was new NameTable() already possible in .NET 1.0?
Teun D
+1  A: 

This problem has been here several times already.

Either you work with namspace-agnostic XPath expressions:

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

or you use a XmlNamespaceManager and register the namespace so you can include a namespace prefix in you 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)
Tomalak
+1  A: 

You need just to register this XML namespaces and associate with a prefix, to make the query work. Create and pass a namespace manager as second parameter when selecting the nodes:

Dim ns As New XmlNamespaceManager ( xmlDoc.NameTable )
ns.AddNamespace ( "msbuild", "http://schemas.microsoft.com/developer/msbuild/2003" )
Dim value As Object = xmlDoc.SelectNodes("/msbuild:Project/msbuild:PropertyGroup/msbuild:ProjectGuid", ns)
baretta