2011-10-16 8 views
8

Soy nuevo en el trabajo con XML, y me he encontrado con un problema extraño al tratar de obtener una etiqueta específica de un archivo de configuración de spring.net. Después de tratar de reducir el problema con un archivo XML de prueba, descubrí que aplicar el siguiente código:No puedo usar Descendientes() o Elementos() con xmlns

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

proporciona una lista no vacía con el siguiente archivo:

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

pero proporciona una cadena vacía con el siguiente archivo:

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

La única diferencia entre los archivos es el atributo.

No puedo imaginar una explicación para esto. Gracias por tu ayuda.

Respuesta

8

Necesitas buscar etiquetas en ese espacio de nombres:

XNamespace ns = "aaa"; 

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

Gracias! Eso hizo el truco, pero también abrió el camino a otro problema. Puedo obtener descendientes llamados "B", por ejemplo, pero no puedo obtener descendientes llamados "db: provider" (no usando "db" ni "db: provider"), lo cual es tristemente lo que tengo que hacer. – Tomata

+0

db aparece como un espacio de nombres diferente. Mi error. – Tomata

+3

@Tomata Si desea ignorar los espacios de nombres, puede escribir algo como: 'var lst = doc.Descendants(). Where (p => p.Name.LocalName ==" B "). ToList();' – xanatos

6

debería especificar el espacio de nombres cuando se consulta a los elementos.

Puede usar el GetDefaultNamespace method para evitar la codificación. También es útil si no sabes lo que es antes de tiempo.

Ejemplo:

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

En uno case, .GetDefaultNamespace no funcionó porque el autor del esquema XML no estaba utilizando xmlns sino xmlns: foo. Puede usar: var ns = xDoc.Root.GetNamespaceOfPrefix ("foo"); – Stonetip

9

sólo por el bien completo:

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

(lo que el otro dice es correcto, pero quería dar otra opción :-))

para Ultra Completeness-sake, si desea buscar ignorando el espacio de nombres:

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