简体   繁体   中英

Silverlight 4.0 reading complex xml with linq

I'm stuck with following XML problem. This is my XML file:

<POIs lastUsedId="9000010">
<POI id="9000010" name="München"><Latitude>48.139126</Latitude><Longitude>11.5801863</Longitude>
<Address>muenchen</Address><PhotoDescription>Hofbräuhaus</PhotoDescription>
<Photos directory="_x002F_pics"><PhotoFile>pic4poi_9000010-01.jpg</PhotoFile> 
<PhotoFile>pic4poi_9000010-02.jpg</PhotoFile><PhotoFile>pic4poi_9000010-03.jpg</PhotoFile>
<PhotoFile>pic4poi_9000010-04.jpg</PhotoFile></Photos>
<InformationFile>infos\info4poi_9000010.txt</InformationFile></POI>
</POIs>

And here is my code to read the file:

XDocument doc = XDocument.Load(s);
                lastID = Int32.Parse(doc.Root.Attribute("lastUsedId").Value.ToString());
                CultureInfo cultureInfo = new CultureInfo("en-GB");
                var pois = from res in doc.Descendants("POI")
                           select new
                           {
                               id = Int32.Parse(res.Attribute("id").Value.ToString()),
                               name = res.Attribute("name").Value.ToString(),
                               latitude = Double.Parse(res.Element("Latitude").Value, cultureInfo),
                               longitude = Double.Parse(res.Element("Longitude").Value, cultureInfo),
                               address = res.Element("Address").Value.ToString(),
                               photoDesc = res.Element("PhotoDescription").Value.ToString(),
                               photoDir = XmlConvert.DecodeName(res.Element("Photos").Attribute("directory").Value.ToString()),
                               photoFiles = from a in doc.Descendants("Photos")
                                            select new
                                            {
                                                photo = a.Element("PhotoFile").Value.ToString()
                                            },
                               info = res.Element("InformationFile").Value.ToString()
                           };
                foreach (var poi in pois)
                {
                    IEnumerable<string> pF = (poi.photoFiles as IEnumerable<string>);
                    List<string> photoFiles = null;
                    if(pF != null)
                        photoFiles = pF.ToList<string>();
                    AddPushpin(poi.id, poi.name, poi.latitude, poi.longitude, poi.address, poi.photoDesc, poi.photoDir, photoFiles, poi.info);
                };

I'm unsure about the part with the PhotoFiles because I get an unknown Object error when I try to read the Pushpin. This what my Pushpin looks like:

public class MyPushpin : Pushpin
{
    public int ID { get; set; }
    public string Address { get; set; }
    public string PhotoDesc { get; set; }
    public string PhotoDir { get; set; }         
    public List<string> PhotoFiles { get; set; }  

    public MyPushpin() { }

    public MyPushpin(int id, string name, double latitude, double longitude, string address, string photoDesc, string photoDir, List<string> photoFiles, string info)
    {
        Location loc = new Location(latitude, longitude);
        this.ID = id;
        this.Location = loc;
        this.Name = name;
        this.Address = address;
        this.PhotoDesc = photoDesc;
        this.PhotoDir = photoDir;
        this.PhotoFiles = photoFiles;
        this.Tag = info;
    }

    public void Update(string name , string photoDesc, List<string> photoFiles, string info)
    {
        this.Name = name;
        this.PhotoDesc = photoDesc;
        this.PhotoFiles = photoFiles;
        this.Tag = info;
    }

    public override string ToString()
    {
        return String.Format("{0} - {1}", this.ID, this.Location, this.Address, this.PhotoDesc, this.PhotoDir, this.Tag);
    }

And that's the code how I would like to use the file info in the custom Pushpin:

public partial class Gallery : ChildWindow
{
    List<string> pics = null;
    public Gallery(MyPushpin currentPin)
    {
        InitializeComponent();
        pics = currentPin.PhotoFiles;
        Loaded += (a, b) => {
            LoadImages();
        };
    }

    private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = true;
        Close();
    }

    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        this.DialogResult = false;
        Close();
    }

    private void LoadImages()
    {
        List<Picture> coll = new List<Picture>();
        pics.ForEach(delegate(String url)
        {
            coll.Add(AddPicture("url"));
        });
        //coll.Add(AddPicture("/pics/pic4poi_9000010-01.jpg"));
        //coll.Add(AddPicture("/pics/pic4poi_9000010-02.jpg"));
        //coll.Add(AddPicture("/pics/pic4poi_9000010-03.jpg"));
        //coll.Add(AddPicture("/pics/pic4poi_9000010-04.jpg"));

        Preview.Source = new BitmapImage(
            new Uri(
                "/pics/pic4poi_9000010-01.jpg",
                UriKind.Relative));
        lbImage.ItemsSource = coll;
    }

    private Picture AddPicture(string path)
    {
        return new Picture
        {
            Href = new BitmapImage(
            new Uri(
                path,
                UriKind.Relative))
        };
    }

    private void lbImage_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Preview.Source = ((Picture)lbImage.SelectedItem).Href;
    }
}
public class Picture
{
    public ImageSource Href { get; set; }

THX for your time Chau

Could you please describe the problem that you are having in more detail. Have you debugged into it, where does it fail, what is the exception? What do you expect it to do.

Off the top of my head, this code looks wrong:

photoFiles = from a in doc.Descendants("Photos")
                                            select new
                                            {
                                                photo = a.Element("PhotoFile").Value.ToString()
                                            },

Replace doc with res, because you want the child elements of the current element, not of the document. Also you can use Elements here instead of Descendants since they are direct children. Also since there are multiple photo files, try a SelectMany (from a... from b...):

photoFiles = from a in res.Elements("Photos")
             from b in a.Elements("PhotoFile")
                                            select new
                                            {
                                                photo = b.Value.ToString()
                                            },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM