Reputation: 183
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]
Upvotes: 2
Views: 345
Reputation: 577
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
Upvotes: 2
Reputation: 3123
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:
Upvotes: 1
Reputation: 140
you need to change
s.Attribute("games").ToString()
x.Attribute("url").ToString()
to:
s.Attribute("games").Value.ToString()
x.Attribute("url").Value.ToString()
Upvotes: 3