2010-04-21 6 views
3

En supposant que vous avez le code XML suivant:Succinct LINQ to XML Query

<?xml version="1.0" encoding="utf-8"?> 

<content> 
    <info> 
     <media> 
      <image> 
       <info> 
        <imageType>product</imageType> 
       </info> 
       <imagedata fileref="http://www.example.com/image1.jpg" /> 
      </image> 
      <image> 
       <info> 
        <imageType>manufacturer</imageType> 
       </info> 
       <imagedata fileref="http://www.example.com/image2.jpg" /> 
      </image> 
     </media> 
    </info> 
</content> 

LINQ to XML, ce qui est la manière la plus succincte, solide pour obtenir un System.Uri pour une image d'un type donné? En ce moment j'ai ceci:

private static Uri GetImageUri(XElement xml, string imageType) 
{ 
    return (from imageTypeElement in xml.Descendants("imageType") 
      where imageTypeElement.Value == imageType && imageTypeElement.Parent != null && imageTypeElement.Parent.Parent != null 
      from imageDataElement in imageTypeElement.Parent.Parent.Descendants("imagedata") 
      let fileRefAttribute = imageDataElement.Attribute("fileref") 
      where fileRefAttribute != null && !string.IsNullOrEmpty(fileRefAttribute.Value) 
      select new Uri(fileRefAttribute.Value)).FirstOrDefault(); 
} 

Cela fonctionne, mais se sent beaucoup trop compliqué. Surtout quand vous considérez l'équivalent XPath.

Quelqu'un peut-il indiquer une meilleure façon?

Répondre

1
var images = xml.Descentants("image"); 

return images.Where(i => i.Descendants("imageType") 
          .All(c => c.Value == imageType)) 
      .Select(i => i.Descendants("imagedata") 
          .Select(id => id.Attribute("fileref")) 
          .FirstOrDefault()) 
      .FirstOrDefault(); 

Donnez qu'un coup :)

+0

+1 Merci, mais il est encore beaucoup plus prolixe que l'équivalent XPath ... –

1
return xml.XPathSelectElements(string.Format("//image[info/imageType='{0}']/imagedata/@fileref",imageType)) 
.Select(u=>new Uri(u.Value)).FirstOrDefault(); 
+0

Peut-être que je l'ai dit plus explicitement: « sans utiliser XPath ». Je suis bien conscient que le XPath est plus succinct, et avait besoin de convaincre de ne pas y passer. Merci quand même. –

+0

@Kent Boogaart: désolé, j'avais mal compris votre question – Gregoire

0

Si vous ne pouvez garantir le fichier aura toujours les données pertinentes, puis sans vérification de type:

private static Uri GetImageUri(XElement xml, string imageType) 
{ 
    return (from i in xml.Descendants("image") 
      where i.Descendants("imageType").First().Value == imageType 
      select new Uri(i.Descendants("imagedata").Attribute("fileref").Value)).FirstOrDefault(); 
} 

Si null vérification est une priorité (et il semble qu'il est):

private static Uri GetSafeImageUri(XElement xml, string imageType) 
{ 
    return (from i in xml.Descendants("imagedata") 
      let type = i.Parent.Descendants("imageType").FirstOrDefault() 
      where type != null && type.Value == imageType 
      let attr = i.Attribute("fileref") 
      select new Uri(attr.Value)).FirstOrDefault(); 
} 

Je ne sais pas si vous aurez beaucoup plus succinct que celui avec null vérification.