2

I am using linq code parsing XML file.This is my code.I want bind detail and image are list.

XmlSerializer serializer = new XmlSerializer(typeof(Notchs));
XDocument xmlDoc = XDocument.Parse(dataInXmlFile);
Notchs notchs = (Notchs)serializer.Deserialize(xmlDoc.CreateReader());

var query = from l in xmlDoc.Descendants("Person")
            select new Notch
            {
                name = (string)l.Attribute("name").Value,
                Titles = l.Element("Details").Elements("detail")
                           .Select(s => s.Attribute("games").ToString())
                           .ToList(),

                Image = l.Element("Details").Elements("detail").Elements("event_image").Elements("image")
                         .Select(x => x.Attribute("url").ToString()).ToList()
            };

foreach (var result in query)
{
    Console.WriteLine(result.name);
    foreach (var detail in result.Titles)
    {
        Console.WriteLine(detail);
    }
}
NotchsList.ItemsSource = query.ToList();

This is i am using XML file and i want to get name and games with image

<?xml version="1.0" encoding="utf-8"?>
<root>
 <Peoples>
  <Person name="Raja">
   <Details>
    <detail games="Cricket">
      <event_image>
        <image  url="http://Cricket.jpeg"/>
      <event_image>
    </detail>
    <detail games="Foot Ball">
     <event_image>
       <image  url="http://FootBall.jpeg"/>
     <event_image>
    </detail>
    <detail games="Volley Ball">
     <event_image>
      <image  url="http://.Volley.jpeg3"/>
     <event_image>
    </detail>
   </Details>
  </Person>
  <Person name="Rama">
    <Details>
     <detail games="Chess">
      <event_image>
        <image  url="http://Chess.jpeg"/1>
      <event_image>
     </detail>
     <detail games="Table Tennis">
      <event_image>
       <image  url="http://TTennis.jpeg"/>
      <event_image>
     </detail>
     <detail games="Carrom">
      <event_image>
       <image  url="http://Carrom.jpeg"/>
      <event_image>
     </detail>
   </Details>
  </Person>
 </Peoples>
</root>

My Code like

public class Notch
{
    [XmlAttribute("name")]
    public string name { get; set; }

    [XmlAttribute("games")]
    public List<string> Titles { get; set; }

    [XmlAttribute("url")]
    public List<string> Image { get; set; }
}


[XmlRoot("root")]
public class Notchs
{
    [XmlArray("Peoples")]
    [XmlArrayItem("Person")]
    [XmlArrayItem("Details")]
    public ObservableCollection<Notch> Collection { get; set; }
}

My xaml file

  <ListBox x:Name="NotchsList" 
        SelectionChanged="NotchsList_SelectionChanged"   Margin="0,-5.25,22,0"  Grid.Row="1" HorizontalAlignment="Right" Width="768" Grid.Column="1" Grid.RowSpan="3" d:LayoutOverrides="VerticalMargin">
        <ListBox.ItemTemplate>
            <DataTemplate>

                    <StackPanel Margin="0,0,0,0" Orientation="Vertical" Grid.ColumnSpan="2"
                        Grid.Column="0"
                        Height="160"
                        VerticalAlignment="Top">
                        <StackPanel Background="#eb2427" Orientation="Vertical">
                            <TextBlock Grid.Row="1"  FontFamily="Calibri" FontSize="34" FontWeight="Bold"  FontStyle="Normal" Margin="10,0,0,0"
                                Text="{Binding name}"
                                   />               
                        </StackPanel>
                        <StackPanel Orientation="Horizontal">
                             <TextBlock Grid.Row="1" FontFamily="Calibri" FontSize="32" Foreground="#a7a9ac"
                                Text="{Binding games}" ScrollViewer.HorizontalScrollBarVisibility="Visible"/>     

                        </StackPanel>
                        <StackPanel Orientation="Horizontal">
                            <Image Grid.Row="1"  Source="{Binding Image}" VerticalAlignment="top" />
                        </StackPanel>           
                </StackPanel>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

I got output like

Raja

  System.collection.generic.list'1[System.String]

  System.collection.generic.list'1[System.String]

Rama

  System.collection.generic.list'1[System.String]

  System.collection.generic.list'1[System.String]
user123
  • 183
  • 2
  • 18

3 Answers3

3

you need to change

s.Attribute("games").ToString()
x.Attribute("url").ToString()

to:

s.Attribute("games").Value.ToString()
x.Attribute("url").Value.ToString()
doiley
  • 140
  • 1
  • 9
  • Hi thanks to replay i tried this but i got error like 1 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?) – user123 Mar 04 '13 at 05:05
  • I don't really understand what each object is so its hard to tell. What is NotchsList.ItemsSource? it's most likely this that is causing the problem. changing it to "var source = query.ToList()" works fine for me. Also, the Deserialize isn't required to get what you want. It's all a little messy to be honest. – doiley Mar 04 '13 at 05:28
  • Hi doiley thanks to your replay i hope ur answer. am new for linq to xml.so please tell me what i want to write? – user123 Mar 04 '13 at 05:42
  • take a look at the other answers, they all provide more info on what you should be doing. I'm not going to just write the same things they have. Hope i've helped. – doiley Mar 04 '13 at 20:59
2

After fixing your XML tag endings - closing all event_image tags and remove the "1" if the chess image as below and removing line 1 and 3 of your code, and the last line - the serializer and call to it which are not used. I got the following output:

Raja
games="Cricket"
games="Foot Ball"
games="Volley Ball"
Rama
games="Chess"
games="Table Tennis"
games="Carrom"

--

<?xml version="1.0" encoding="utf-8"?>
<root>
  <Peoples>
    <Person name="Raja">
      <Details>
        <detail games="Cricket">
          <event_image>
            <image  url="http://Cricket.jpeg"/>
          </event_image>
        </detail>
        <detail games="Foot Ball">
          <event_image>
            <image  url="http://FootBall.jpeg"/>
          </event_image>
        </detail>
        <detail games="Volley Ball">
          <event_image>
            <image  url="http://.Volley.jpeg3"/>
          </event_image>
        </detail>
      </Details>
    </Person>
    <Person name="Rama">
      <Details>
        <detail games="Chess">
          <event_image>
            <image  url="http://Chess.jpeg"/>
          </event_image>
        </detail>
        <detail games="Table Tennis">
          <event_image>
            <image  url="http://TTennis.jpeg"/>
          </event_image>
        </detail>
        <detail games="Carrom">
          <event_image>
            <image  url="http://Carrom.jpeg"/>
          </event_image>
        </detail>
      </Details>
    </Person>
  </Peoples>
</root>

This is produced using your code Copy-pasted but I removed the following lines:

XmlSerializer serializer = new XmlSerializer(typeof(Notchs)); //first line
Notchs notchs = (Notchs)serializer.Deserialize(xmlDoc.CreateReader()); //third line
NotchsList.ItemsSource = query.ToList(); //last line in your code snippet
  • @user123: He tried your code - fix the malformed xml and remove the unused serializer. It's your code that produces this result. – pescolino Mar 04 '13 at 13:54
  • As @pescolino said. I've also went ahead and explicitly listed the lines I removed to get it to work. P.S. thanks pescolino for a more timely response. – Infinite Possibilities Mar 04 '13 at 15:59
  • yes you are telling correct but where can you show the output? NotchList is the listbox x:Name.i through the output via listbox – user123 Mar 06 '13 at 09:28
  • @Infinite Possiblities first thing i want bind games with images and second thing is lists want horizontal scroll view like cricket below cricket image,football below football image. – user123 Mar 07 '13 at 07:25
1

As others already mentioned your XML has a few typos. After fixing that and removing the unused XmlSerializer your query produces a valid IEnumerable<Notch>. Everything works as expected.

But I strongly doubt that you want to have the full attributes in your Titles list. Actually you want to have their values. So you have to write Attribute(...).Value and omit ToString():

var query = from l in xmlDoc.Descendants("Person")
            select new Notch
            {
                name = (string)l.Attribute("name").Value,
                Titles = l.Element("Details").Elements("detail")
                          .Select(s => s.Attribute("games").Value)
                          .ToList(),

                Image = l.Element("Details").Elements("detail")
                         .Elements("event_image").Elements("image")
                         .Select(x => x.Attribute("url").Value).ToList()
            };

foreach (var result in query)
{
    Console.WriteLine(result.name);
    foreach (var detail in result.Titles.Zip(result.Image, (st, si) => string.Format("{0} {1}", st, si)))
    {
        Console.WriteLine(detail);
    }
}

Note that I used the Zip extension method to combine related titles and image urls. But this is only for a better output. The data is already correct. This is the output:

Raja
Cricket http://Cricket.jpeg
Foot Ball http://FootBall.jpeg
Volley Ball http://.Volley.jpeg3
Rama
Chess http://Chess.jpeg
Table Tennis http://TTennis.jpeg
Carrom http://Carrom.jpeg

However your data will not show up in your listbox. You bind to games instead of Titles and you use TextBlock to show a list which produces the output you mentioned. It should also be a ListBox. Here is a "slightly" simplified but working version:

<ListBox x:Name="NotchsList">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding name}" />
        <StackPanel Orientation="Horizontal">
          <ListBox ItemsSource="{Binding Titles}" Width="200" />
          <ListBox ItemsSource="{Binding Image}" Width="200" />
        </StackPanel>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

And this is how it looks:

output.png

pescolino
  • 3,086
  • 2
  • 14
  • 24
  • hi i hope your answer i got same thing above your answer but i need images not like path – user123 Mar 05 '13 at 08:50
  • hi i want scroll below the image with title.you are getting values to list box.i dont want bind this type i want name below image want scroll with title.so please tel me any idea..., – user123 Mar 05 '13 at 10:55
  • @user123: You need a [listbox with horizontal layout](http://stackoverflow.com/questions/1292516/wpf-listbox-that-lays-out-its-items-horizontally). Also you must actually [download the images](http://stackoverflow.com/questions/3659574/synchronously-download-an-image-from-url). – pescolino Mar 05 '13 at 12:17