2011-10-16 13 views
8

Sono nuovo a lavorare con XML e ho riscontrato uno strano problema durante il tentativo di ottenere un tag specifico da un file di configurazione di spring.net. Dopo aver cercato di circoscrivere il problema con un file XML di test, ho scoperto che applicando il codice seguente:Impossibile utilizzare Descendants() o Elements() con xmlns

List<XElement> nodes = xmlFile.Descendants("B").ToList(); 

fornisce una lista non vuota con il seguente file:

<?xml version="1.0" encoding="utf-8" ?> 
<A fakeAttribute="aaa"> 
    <B id="DbProvider"/> 
</A> 

ma fornisce un stringa vuota con il seguente file:

<?xml version="1.0" encoding="utf-8" ?> 
<A xmlns="aaa"> 
    <B id="DbProvider"/> 
</A> 

L'unica differenza tra i file è l'attributo.

Non riesco a immaginare una spiegazione per questo. Grazie per l'aiuto.

risposta

8

è necessario cercare per i tag in quel namespace:

XNamespace ns = "aaa"; 

xmlFile.Descendants(ns + "B").ToList() 
+0

Grazie! Questo ha fatto il trucco, ma ha anche aperto la strada a un altro problema. Posso ottenere discendenti chiamati "B", ad esempio, ma non posso ottenere discendenti con il nome "db: provider" (non usando "db" né "db: provider"), che è purtroppo esattamente quello che devo fare. – Tomata

+0

db è elencato come spazio dei nomi diverso. Colpa mia. – Tomata

+3

@Tomata Se si desidera ignorare i namespace, è possibile scrivere qualcosa come: 'var lst = doc.Descendants(). Where (p => p.Name.LocalName ==" B "). ToList();' – xanatos

6

è necessario specificare lo spazio dei nomi durante la ricerca di elementi.

È possibile utilizzare GetDefaultNamespace method per impedirne la codifica. È anche utile se non sai cosa è in anticipo.

Esempio:

var ns = xmlFile.GetDefaultNamespace(); 
var nodes = xmlFile.Descendants(ns + "B").ToList(); 
+0

In uno caso, .GetDefaultNamespace non ha funzionato perché l'autore dello schema XML non stava usando xmlns ma piuttosto xmlns: foo. È possibile utilizzare: var ns = xDoc.Root.GetNamespaceOfPrefix ("foo"); – Stonetip

9

Solo per completezza bene:

var lst = doc.Descendants("{aaa}B").ToList(); 

(ciò che l'altro ha detto è corretto, ma ho voluto dare un'altra possibilità :-))

per Ultra completezza-sake, se si vuole cercare ignorando lo spazio dei nomi:

var lst = doc.Descendants().Where(p => p.Name.LocalName == "B").ToList();