2010-01-28 13 views
6
var subset = from item in document.Descendants("Id") 
      where item.Value == itemId.ToString() 
      select new PurchaseItem() { 
       Id = int.Parse(item.Parent.Element("Id").Value), 
       Name = item.Parent.Element("Name").Value, 
       Description = item.Parent.Element("Description").Value, 
       Price = int.Parse(item.Parent.Element("Price").Value) 
      }; 

La estructura del XML es el siguiente:¿Linq-XML siempre es tan desordenado?

<Items> 
    <Item> 
     <Id></Id> 
     <Name></Name> 
     <Description></Description> 
     <Price></Price> 
    </Item> 
</Items> 

Id, y el precio son ambos valores enteros. El nombre y la descripción son cadenas.

He encontrado Linq to XML ideal para lo que lo he usado, esto es solo un fragmento. Pero, por otro lado, tengo la sensación de que debería o podría ser más limpio. El casting parece el problema más obvio en este fragmento.

¿Algún consejo?

+1

trate de hacer esto utilizando XmlReader, o incluso el viejo XML DOM, y volverá a evaluar su vista de 'desordenado'. ;) – Noldorin

+0

La sintaxis aquí sería mucho más clara con la dinámica. Imagine 'ID = item.Id', etc. –

+0

@Noldorin - 'untidy' sería más adecuado que eso;) Mi trabajo con XMLReader en el pasado, ahora que era desordenado. – Finglas

Respuesta

13

En realidad, sería mejor IMO para emitir que llamar al int.Parse. Así es como yo iba a escribir su consulta:

string id = itemId.ToString(); // We don't need to convert it each time! 

var subset = from item in document.Descendants("Id") 
      where item.Value == id 
      let parent = item.Parent 
      select new PurchaseItem 
      { 
       Id = (int) parent.Element("Id"), 
       Name = (string) parent.Element("Name"), 
       Description = (string) parent.Element("Description"), 
       Price = (int) parent.Element("Price") 
      }; 
+2

hombre, eres rápido ... –

+0

John, ¿algún comentario sobre por qué lo haces de esta manera, en lugar de la forma en que lo muestro? –

+0

@Jon - ¿Cómo es que no se requiere .Value? ¿Esto se llama implícitamente detrás de la escena? – Finglas

1

Supongo que también tiene un nodo "Artículos"

que podría hacer algo como esto, suponiendo que está cargando el documento utilizando XElement.Load()

var subset = from item in document.Elements("Item") 
      where item.Element("Id").Value == itemId.ToString() 
      select new PurchaseItem() { 
       Id = int.Parse(item.Element("Id").Value), 
       Name = item.Element("Name").Value, 
       Description = item.Element("Description").Value, 
       Price = int.Parse(item.Element("Price").Value) 
      }; 

No mucho mejor, pero mucho más fácil de leer!

1

En su ejemplo se puede poner en orden un poco encontrando el elemento <Item/> en lugar de la <Id/> para evitar que el Parent cada vez:

var subset = from item in document.Descendants("Item") 
      where item.Element("Id").Value == itemId.ToString() 
      select new PurchaseItem() 
         { 
          Id = int.Parse(item.Element("Id").Value), 
          Name = item.Element("Name").Value, 
          Description = item.Element("Description").Value, 
          Price = int.Parse(item.Element("Price").Value) 
         }; 
+0

Originalmente tuve esto, pero lo cambié después de jugar con el código. Entonces +1 por mostrarme que se puede hacer. – Finglas

1

Considérese escribir un nuevo constructor para PurchaseItem que lleva el elemento XML, para que pueda escribir:

select new PurchaseItem(item.Parent);