Su un .vbproj y parece que esta

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

todo lo que quiero conseguir es el ProjectGuid pero no funciona cuando hay un espacio de nombres es lo que hay…

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

¿qué puedo hacer para solucionar esto?

  • Dos problemas con annakata la solución: 1. Es feo, 2. En este caso puede ser utilizado, pero proporcionará resultados equivocados si un ‘ProjectGuid’ elemento pertenece a más de un espacio de nombres y queremos que los elementos sólo desde un único espacio de nombres. Soluciones mediante el uso de la NamespaceManager son mejores
  • El XPath motor debe ser proporcionada con la derecha contexto estático que contiene los enlaces entre los prefijos y NS URIs para utilizar al evaluar expresiones o usted no será capaz de hacer referencia a cosas dentro de los espacios de nombres. Esto es lo que @Teun hace.
InformationsquelleAutor Peter | 2009-02-11

6 Comentarios

  1. 44

    La mejor manera de hacer cosas como esta (en mi humilde opinión) es crear un espacio de nombres del administrador. Esto puede ser usado llamar SelectNodes para indicar que el espacio de nombres de direcciones Url están conectados a que los prefijos. Yo normalmente para configurar una propiedad estática que devuelve una instancia adecuada como esto (es C#, vas a tener que traducir):

    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;
      }
    }

    Yo sólo incluyen un espacio de nombres aquí, pero usted podría tener varias. A continuación, puede seleccionar el documento como este:

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

    Tenga en cuenta que todos los elementos están en el espacio de nombres especificado.

    • usted no necesita crear un nuevo XmlDocument para obtener un XmlNameTable. usted puede utilizar nsMgr = new XmlNamespaceManager(nueva NameTable());
    • Ah, gracias. Nunca encontré la forma de hacerlo. Era nuevo NameTable() posible .NET 1.0?
    • Es increíble cuánto tiempo se puede guardar en el largo plazo para el uso de espacios de nombres correctamente en el primer lugar.
  2. 63

    Probablemente estaría inclinado a ir con Bartek del* espacio de nombres de la solución, pero un xpath general de la solución es:

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

    **desde Bartek la respuesta ha desaparecido, recomiendo Teun (que es en realidad más profunda)*

    • De acuerdo, aunque este se convierte en un verdadero PITA cuando usted tiene que ir más allá de un par de niveles de profundidad. En no de trabajo, sin embargo. 🙂
    • bastante, es por eso que me gustaría ir con Barteks – lo único que me detiene es el caso si no sé los nombres de antemano o lo puedo garantizar, en cuyo caso probablemente me lave toda la doc primera, pero diciendo lo que sólo me stalker downvotes 🙂
    • Dos problemas con esto: 1. Es feo, 2. En este caso puede ser utilizado, pero proporcionará resultados equivocados si un ‘ProjectGuid’ elemento pertenece a más de un espacio de nombres y queremos que los elementos sólo desde un único espacio de nombres. Soluciones mediante el uso de la NamespaceManager son mejores.
    • Me sorprende que aún no votada abajo ya
    • Yo downvote algo que es totalmente erróneo, no es algo que una solución, aunque no la mejor
    • Usted es un caballero y un erudito
    • Probablemente sería más robusto mencionar que este es un hackeado solución, y por qué…
    • Sin embargo, funciona esta no es una eficiente manera de hacerlo. La forma correcta sería cargar el selector xpath con los espacios de nombres.
    • buena captura, esta es una buena manera de no declarar aburrido y caro espacios de nombres
    • Esto es genial, declarando todos estos espacios de nombres hace XPath más problemas de lo que vale la OMI.

  3. 27

    Este problema ha sido aquí varios veces ya.

    Ya sea que el trabajo con el espacio de nombres independiente de expresiones XPath (no se recomienda para su torpeza y el potencial de falsos positivos partidos – <msb:ProjectGuid> y <foo:ProjectGuid> son los mismos para esta expresión):

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

    o hacer lo correcto y el uso de un XmlNamespaceManager para registrar el URI de espacio de nombres, de modo que usted puede incluir un prefijo de espacio de nombres en su 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)
  4. 3

    Usted necesita sólo para registrar esta espacios de nombres XML y se asocian con un prefijo, para hacer el trabajo de consulta.
    Crear y aprobar un espacio de nombres manager como segundo parámetro la hora de seleccionar los nodos:

    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)
  5. 0

    Es una forma de utilizar las extensiones de + NameSpaceManager.

    Código en VB, pero es realmente fácil de traducir a C#.

    Imports System.Xml
    Imports System.Runtime.CompilerServices
    Public Module Extensions_XmlHelper
    'XmlDocument Extension for SelectSingleNode
    <Extension()>
    Public Function _SelectSingleNode(ByVal XmlDoc As XmlDocument, xpath As String) As XmlNode
    If XmlDoc Is Nothing Then Return Nothing
    Dim nsMgr As XmlNamespaceManager = GetDefaultXmlNamespaceManager(XmlDoc, "x")
    Return XmlDoc.SelectSingleNode(GetNewXPath(xpath, "x"), nsMgr)
    End Function
    'XmlDocument Extension for SelectNodes
    <Extension()>
    Public Function _SelectNodes(ByVal XmlDoc As XmlDocument, xpath As String) As XmlNodeList
    If XmlDoc Is Nothing Then Return Nothing
    Dim nsMgr As XmlNamespaceManager = GetDefaultXmlNamespaceManager(XmlDoc, "x")
    Return XmlDoc.SelectNodes(GetNewXPath(xpath, "x"), nsMgr)
    End Function
    Private Function GetDefaultXmlNamespaceManager(ByVal XmlDoc As XmlDocument, DefaultNamespacePrefix As String) As XmlNamespaceManager
    Dim nsMgr As New XmlNamespaceManager(XmlDoc.NameTable)
    nsMgr.AddNamespace(DefaultNamespacePrefix, XmlDoc.DocumentElement.NamespaceURI)
    Return nsMgr
    End Function
    Private Function GetNewXPath(xpath As String, DefaultNamespacePrefix As String) As String
    'Methode 1: The easy way
    Return xpath.Replace("/", "/" + DefaultNamespacePrefix + ":")
    ''Methode 2: Does not change the nodes with existing namespace prefix
    'Dim Nodes() As String = xpath.Split("/"c)
    'For i As Integer = 0 To Nodes.Length - 1
    '    'If xpath starts with "/", don't add DefaultNamespacePrefix to the first empty node (before "/")
    '    If String.IsNullOrEmpty(Nodes(i)) Then Continue For
    '    'Ignore existing namespaces prefixes
    '    If Nodes(i).Contains(":"c) Then Continue For
    '    'Add DefaultNamespacePrefix
    '    Nodes(i) = DefaultNamespacePrefix + ":" + Nodes(i)
    'Next
    ''Create and return then new xpath
    'Return String.Join("/", Nodes)
    End Function
    End Module

    Y a utilizar:

    Imports Extensions_XmlHelper
    ......
    Dim FileXMLTextReader As New XmlTextReader(".....")
    FileXMLTextReader.WhitespaceHandling = WhitespaceHandling.None
    Dim xmlDoc As XmlDocument = xmlDoc.Load(FileXMLTextReader)
    FileXMLTextReader.Close()
    ......
    Dim MyNode As XmlNode = xmlDoc._SelectSingleNode("/Document/FirstLevelNode/SecondLevelNode")
    Dim MyNode As XmlNodeList = xmlDoc._SelectNodes("/Document/FirstLevelNode/SecondLevelNode")
    ......
  6. -7

    ¿Por qué no utilizar el //ignorar el espacio de nombres:

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

    //actúa como comodín para seguir a través de todo lo que entre la raíz y el siguiente nombre de nodo especificado(he.e ProjectGuid)

    • en realidad no trabajo – sí, esto dice mira para cualquier ProjectGuids en cualquier lugar, pero todavía quiere los mismos dentro del espacio de nombres predeterminado

Dejar respuesta

Please enter your comment!
Please enter your name here