2009-08-01 6 views
1

J'ai un fichier xml qui ressemble à ceci et j'essaye d'obtenir tous les attributs d'emplacement dans une cellule de tableau. J'ai réussi à obtenir le titre et la description mais je n'arrive pas à obtenir tous les emplacements dans les événements.xml imbriqué avec linq dans le répéteur

Quelqu'un peut-il m'aider à ce sujet?

Vive Terry

Ce que je suis venu est jusqu'à présent les éléments suivants

var qListCurrentMonth = (from feed in doc.Descendants("item") 
         select new 
         { 
          title = feed.Element("title").Value, 
          description = feed.Element("description").Value, 
          events = (from ev in feed.Element("events").Elements("location") 
             select new 
               { 
                city = ev.Attribute("city") 
               }).ToList() 
         }); 

rptFeedItems.DataSource = qListCurrentMonth; 
rptFeedItems.DataBind(); 

et ici le xml

Events Défilé de mode 1

<description>item descr</description> 
    <link>http://somelink</link> 

    <events> 
    <location city="nyc" date="12.12.08" link="http://www.etc.com" /> 
    <location city="nyc" date="25.11.08" link="http://www.etc.com" /> 
    <location city="sfo" date="11.11.08" link="http://www.etc.com" /> 
    <location city="sfo" date="22.01.08" link="http://www.etc.com" /> 
    <location city="dal" date="12.12.08" link="http://www.etc.com" /> 

    </events> 
</item> 

<item> 
    <title>Fashion show 2</title> 

    <description>item descr</description> 
    <link>http://somelink</link> 

    <events> 
    <location city="nyc" date="12.12.08" link="http://www.etc.com" /> 
    <location city="nyc" date="25.11.08" link="http://www.etc.com" /> 
    <location city="sfo" date="11.11.08" link="http://www.etc.com" /> 
    <location city="sfo" date="22.01.08" link="http://www.etc.com" /> 
    <location city="dal" date="12.12.08" link="http://www.etc.com" /> 

    </events> 
</item> 

et ici le répéteur

<table border="1"> 
      <asp:Repeater runat="server" ID="rptFeedItems"> 
       <ItemTemplate> 
        <tr> 
         <td><%# Eval("title")%></td> 
         <td><%# Eval("description")%></td> 
         <td><%# Eval("events")%></td> 
        </tr> 

       </ItemTemplate> 
      </asp:Repeater> 

     </table> 
+1

Avez-vous envisagé d'utiliser XSLT? :-) –

+0

Je ne peux pas imaginer un cas où l'on voudra utiliser XSLT s'il peut utiliser LINQ en XML. Cela étant dit, il y a des raisons légitimes pour XSLT comme quand il y a un besoin d'interopérabilité avec les systèmes non-NET et quand la transformation doit être fournie au système plus tard et permettre LINQ to XML peut être un risque de sécurité parce qu'il peut être utilisé pour injecter du code arbitraire. – Stilgar

Répondre

1

Je suppose que vous obtenez le type de liste générique au lieu de la valeur de l'élément. En effet, Eval renvoie le résultat ToString() et ToString() sur une liste renvoie le type. Il y a plusieurs choses que vous pouvez faire. L'un imbrique un autre répéteur et le lie à la propriété events. C'est la solution la plus propre en théorie bien que dans ce cas je doute que cela en vaille la peine.

Une autre chose que vous pouvez faire est d'accumuler la propriété events en tant que chaîne. cela peut être fait comme ceci:

var qListCurrentMonth = 
    (from feed in doc.Descendants("item") 
    select new 
    { 
     title = feed.Element("title").Value, 
     description = feed.Element("description").Value, 
     events = 
      (from ev in feed.Element("events").Elements("location") 
      select ev.Attribute("city").Value).Aggregate((x,y) => x+ "<br />" + y) 
     }); 

La méthode Aggregate va accumuler la collection dans une instance unique. Si vous avez plus de 5 événements par ligne moyenne, vous feriez mieux d'utiliser StringBuilder comme un accumulateur (il y a une surcharge d'Aggregate) pour des raisons de performances (je suis sûr que vous connaissez la chaîne vs StringBuilder et les performances).

Depuis que vous utilisez .NET 3.5, je conseille d'utiliser ListView au lieu de Répéteur ... comme toujours. Dans ce cas aussi, un GridView peut être meilleur puisque vous représentez une table.

Enfin - s'il vous plaît suivre la convention .NET et utiliser PascalCase pour les noms de propriété (à savoir des événements au lieu d'événements)

+0

Merci beaucoup Stilgar, je n'aurais jamais pensé à utiliser la méthode agrégée. –

1

Si vous voulez juste la liste des codes de la ville dans votre cellule d'événements:

var qListCurrentMonth = 
    from feed in doc.Descendants("item") 
    let cities = 
     (from location in feed.Element("events").Elements("location") 
     select location.Attribute("city").Value) 
     .ToArray()) 
    select new 
    { 
     title = feed.Element("title").Value, 
     description = feed.Element("description").Value, 
     events = string.Join(", ", cities) 
    }); 

La méthode Aggregate de Stilgar est également une excellente suggestion.