2009-04-20 19 views
10

Il mio requisito di base è ottenere il valore dell'elemento dal file XML, ho usato XMLDoxument.SelectSingleNode. Il mio file XML contiene un po 'di spazio dei nomi nell'intestazione, quindi ho usato NameSpaceManager per aggiungere il prefisso dello spazio dei nomi e ho usato il prefisso per ottenere quel particolare elemento. Ora nei miei file XML che gli spazi dei nomi stanno cambiando, non voglio fare alcun hard coding, c'è un modo per trovare tutti gli spazi dei nomi e posso aggiungerlo a NameSpaceManager.come posso elencare tutto lo spazio dei nomi in XML?

Grazie.

+0

@Ruchita: il problema con questo approccio è che le dichiarazioni di spazi dei nomi possono essere sovrascritte (in XML 1.0 la dichiarazione dello spazio dei nomi predefinita può anche essere reimpostata, in XML 1.1 tutte le dichiarazioni di namespace) –

risposta

2

Il problema di base relativo al recupero degli spazi dei nomi da un XmlDocument può essere risolto semplicemente recuperando NameTable di XmlDocument e creando uno XmlNameSpaceManager da esso.

Tuttavia, se si desidera elencare gli spazi dei nomi per altri scopi, è necessario controllare il metodo GetNamespacesInScope esposto dalla classe XmlNamespaceManager e la classe XPathNavigator.

Quando si utilizza un XmlDocument, è possibile ottenere un XmlNamespaceManager da esso tramite il seguente codice:

//Instantiate an XmlDocument object. 
XmlDocument xmldoc = new XmlDocument(); 

//Load XML file into the XmlDocument object. 
xmldoc.Load("C:\\myFile.xml"); 

//Instantiate an XmlNamespaceManager object. 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable); 

// Retrieve the namespaces into a Generic dictionary with string keys. 
IDictionary<string, string> dic = nsMgr.GetNamespacesInScope(XmlNamespaceScope.All); 

// Iterate through the dictionary. 

... 

In this article, Scott Hanselman presenta un modo per utilizzare questo metodo per elencare tutti gli spazi dei nomi in un documento utilizzando un XPathNavigator e usando un ponte LINQ.

+2

Questo non sembra funzionare per me. Ci sono molti articoli nel NameTable del documento, ma diversi spazi dei nomi definiti all'inizio del documento non vengono aggiunti a XmlNamespaceManager. Continuo a ricevere "Namespace non definito" nelle mie chiamate SelectNodes, a meno che non aggiungo manualmente gli spazi dei nomi al gestore. Ho bisogno di una soluzione che legga con precisione gli spazi dei nomi definiti nel documento XML e li aggiunga al mio gestore dello spazio dei nomi, in modo da non doverli codificare. –

+0

@SeanWorle È un po 'tardi, ma controlla [Ottieni spazi dei nomi da un documento XML con XPathDocument e LINQ su XML] (http://www.hanselman.com/blog/CommentView.aspx?guid=51861b63-526f-4572- ba84-2f24a1c7bd83), forse potrebbe aiutare te o qualcun altro. – ErikE

+1

Il problema con questo approccio è che ignora le voci "xmlns". –

7

Grazie per la vostra risposta rapida ...

penso che la versione di .NET che si sta utilizzando e quale deve essere più recente. Sto usando .NET Framework 1.1 ... piuttosto vecchio :(..

Con il tempo ,, ho avuto alcuni esempi di codice in questo modo .. per lo stesso scopo ...

XmlNodeList _xmlNameSpaceList = _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]"); 

      _xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);   

      foreach(XmlNode nsNode in _xmlNameSpaceList) 
      { 
       _xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value); 
      } 

Qualsiasi commento sarà apprezzato per aggiungere conoscenza al mio KB ... Grazie

+0

buon vecchio XPath, funziona perfettamente, recupera tutti i nodi con namespace. Grazie – zulucoda

-2

Se stai cercando un modo rapido per evitare il problema dello spazio dei nomi, rimuovere le definizioni dello spazio dei nomi dall'Xml tramite una RegEx prima di eseguire XmlDocument .LoadXml (bla). Lo faccio quando analizzo pagine XHTML live. Prende il tempo di caricamento di XmlDoc da 15 secondi a 0,15 secondi e fa in modo che non debba precedere i miei xpath .

13

Gli spazi dei nomi possono essere trovati ovunque all'interno del documento xml. Quindi, per estrarre tutti gli spazi dei nomi e li dichiara in una XmlNamespaceManager ho fatto la seguente:

public static XmlNamespaceManager getAllNamespaces(XmlDocument xDoc) 
{ 
    XmlNamespaceManager result = new XmlNamespaceManager(xDoc.NameTable); 

    IDictionary<string, string> localNamespaces = null; 
    XPathNavigator xNav = xDoc.CreateNavigator(); 
    while (xNav.MoveToFollowing(XPathNodeType.Element)) 
    { 
     localNamespaces = xNav.GetNamespacesInScope(XmlNamespaceScope.Local); 
     foreach (var localNamespace in localNamespaces) 
     { 
      string prefix = localNamespace.Key; 
      if (string.IsNullOrEmpty(prefix)) 
        prefix = "DEFAULT"; 

      result.AddNamespace(prefix, localNamespace.Value); 
     } 
    } 

    return result; 
} 

Basta prestare attenzione al caso spazio dei nomi predefinito. Ho ridefinito lo spazio dei nomi predefinito come prefisso "DEFAULT" perché ho riscontrato dei problemi durante l'esecuzione di SelectSingleNode utilizzando il gestore dello spazio dei nomi sopra riportato durante l'interrogazione dello spazio dei nomi predefinito. Ero la mia soluzione. Spero che questo aiuti

0

Ruchita ha pubblicato la soluzione di lavoro per XmlDocument. Ma volevo fare lo stesso con XDocument. Qui è la stessa con XDocument:

var xml = XDocument.Load(filename); 
var xmlNameSpaceList = ((IEnumerable)xml.XPathEvaluate(@"//namespace::*[not(. = ../../namespace::*)]")).Cast<XAttribute>(); 
var xmlNSmgr = new XmlNamespaceManager(new NameTable()); 
foreach (var nsNode in xmlNameSpaceList) 
{ 
    xmlNSmgr.AddNamespace(nsNode.Name.LocalName, nsNode.Value); 
} 

Ora è possibile utilizzare XPath con spazi dei nomi, per esempio xml.XPathEvaluate("//test:p", xmlNSmgr).

Problemi correlati