XDocument czytanie pliku XML

0

Posiadam xml o takiej strukturze (na cele edukacyjne zmieniona zawartość ;))

<?xml version="1.0" encoding="UTF-8"?>
<trasy>
	<trasa nrTrasy = "1">
	<nazwaTrasy>Trasa1</nazwa>
	<Punkt nrPunktu = "1">
		<nazwaPunktu>Warszawa </nazwaPunktu>
		<czasPobytu>10</czasPobytu>
	</Punkt>
	<Punkt nrPunktu = "2">
		<nazwaPunktu>Gdynia </nazwaPunktu>
		<czasPobytu>15</czasPobytu>
	</Punkt>
	<Punkt nrPunktu = "3">
		<nazwaPunktu>Gdansk </nazwaPunktu>
		<czasPobytu>5</czasPobytu>
	</Punkt>
	</trasa>
	<trasa nrTrasy = "2">
	<nazwaTrasy>Trasa2</nazwa>
	<Punkt nrPunktu = "1">
		<nazwaPunktu>Krakow </nazwaPunktu>
		<czasPobytu>10</czasPobytu>
	</Punkt>
	<Punkt nrPunktu = "2">
		<nazwaPunktu>Zakopane </nazwaPunktu>
		<czasPobytu>15</czasPobytu>
	</Punkt>
	<Punkt nrPunktu = "3">
		<nazwaPunktu>Kielce </nazwaPunktu>
		<czasPobytu>5</czasPobytu>
	</Punkt>
	</trasa>
</trasy>

Do tego w programie mam dwie klasy

public class Trasa
{
        public int nrTrasy { get; set; }
        public string nazwaTrasy { get; set; }
        list<Punkt> listaPunktow;

        public Trasa(int nrTrasy , string nazwaTrasy , list<Punkt> listaPunktow)
        {
            this.nrTrasy = nrTrasy ;
            this.nazwaTrasy = nazwaTrasy ;
            this.listaPunktow = listaPunktow;
        }
}

public class Punkt
{
        public int nrPunktu { get; set; }
        public string nazwaPunktu { get; set; }
        public int czasPobytu { get; set; }

        public Punkt(int nrPunktu , string nazwaPunktu , int czasPobytu )
        {
            this.nrPunktu = nrPunktu ;
            this.nazwaPunktu = nazwaPunktu ;
            this.czasPobytu = czasPobytu ;
        }
}

Chciałbym w klasie czytającej Xml stworzyć listę tras

public XmlReader
{
 public List<Trasa> GetXml()
        {
            
            XDocument xml = XDocument.Load("dane.xml");
            List<Trasa> trasa = (
                from trasa in xml.Root.Elements("trasa")
                select new Trasa(
                    int.Parse(trasa.Attribute("nrTrasy").Value),
                    trasa.Element("nazwaTrasy").Value
                ).ToList<Trasa>();
            return trasa;
        }
}

Edit:
Edytowałem zarówno xml jak i klasy i metodę. Teraz przypomina bardziej założenie tego co mam zrobić i ma chyba większy sens niż przykład ze zwierzętami.
Jak za pomocą XDocument to zrobić?
Bo o ile wyciągnięcie nrTrasy i nazwy dla trasy, co jest w kodzie wyżej, tylko należy wtedy z konstruktora wywalić listę punktow, to nie potrafię dostać się do bardziej zagnieżdżonych elementów.
W jaki sposób można to rozwiązać?

Albo inaczej jak podejść do problemu żeby z takiego xml'a wyciągnąć trasy i żeby każda z tras miała oprócz atrybutu i nazwy listę punktów z wartościami danych punktów?

0

Oj nie, to wszystko jest nie tak. Przede wszystkim zrób wcięcia w XML, który wkleiłeś, bo niczego nie widać.

Klasa Ssaki. Dlaczego posiada listę psów? Niestety nie ogarniasz dziedziczenia i obiektowości. Powinieneś mieć klasę Ssak. Może ta klasa mieć jakiś nr grupy. Ale nazwa? Może imię? To by się jeszcze broniło.

Może mieć też jakieś swoje Id.

Po klasie ssak powinna dziedziczyć klasa Psy.

Później te wszystkie dane z XML możesz mieć w liście: List<Ssak>.

Ciężko mi cokolwiek więcej wytłumaczyć, bo nie wiem co chcesz osiągnąć. Ale na pewno robisz to źle od samego początku. Ten system powinien być inaczej zaprojektowany.

0

Zdecyduj się jaki masz problem. Wcześniej pisałeś o ssakach i psach, teraz o trasach :/

0

Niestety nie pomogę, ponieważ podany przez Ciebie dokument jest nieprawidłowym dokumentem XML - zwiera błędy.

0

Wstawiam poprawiony XML. Sprawdziłem validatorem i nie ma błędów.

<?xml version="1.0" encoding="UTF-8"?>
<trasy>
    <trasa nrTrasy = "1">
    <nazwaTrasy>Trasa1</nazwaTrasy>
    <Punkt nrPunktu = "1">
        <nazwaPunktu>Warszawa </nazwaPunktu>
        <czasPobytu>10</czasPobytu>
    </Punkt>
    <Punkt nrPunktu = "2">
        <nazwaPunktu>Gdynia </nazwaPunktu>
        <czasPobytu>15</czasPobytu>
    </Punkt>
    <Punkt nrPunktu = "3">
        <nazwaPunktu>Gdansk </nazwaPunktu>
        <czasPobytu>5</czasPobytu>
    </Punkt>
    </trasa>
    <trasa nrTrasy = "2">
    <nazwaTrasy>Trasa2</nazwaTrasy>
    <Punkt nrPunktu = "1">
        <nazwaPunktu>Krakow </nazwaPunktu>
        <czasPobytu>10</czasPobytu>
    </Punkt>
    <Punkt nrPunktu = "2">
        <nazwaPunktu>Zakopane </nazwaPunktu>
        <czasPobytu>15</czasPobytu>
    </Punkt>
    <Punkt nrPunktu = "3">
        <nazwaPunktu>Kielce </nazwaPunktu>
        <czasPobytu>5</czasPobytu>
    </Punkt>
    </trasa>
</trasy>

Ogólnie najbardziej to mnie interesuje jak dostać się do Punktów i stworzyć ich listę. Wcześniej zamiast tras i punktów były ssaki. Zmieniłem żeby wyglądało to sensowniej. Ale treść XML'a nie ma dla mnie jakiegoś większego znaczenia tylko jego struktura.
W obecnej formie potrzebuje z XML wyciągnąć Listę tras, a każda trasa ma zawierać swój numer, nazwę i listę punktów. Natomiast każdy punkt musi w sobie zawierać nr punktu, nazwę i czas pobytu.

0

Chyba wiem o co Tobie chodzi - chcesz to wszystko zrobić w jednej instrukcji xD Nie da się.
Na pewno wiesz jak się dostać do punktów, skoro wiesz jak do trasy.

0

No właśnie chodziło mi o to czy dam radę w tym jednym select jakoś dostać się jeszcze do punktów czy trzeba dwie różne instrukcje

0

W notacji z kropką się da:

document
                .Descendants()
                .Where(n => n.Name.LocalName.Equals("trasa"))
                .Select(n => 
                {
                    

                    //return trasa
                });

Z tym że to dobry kod nie będzie. Powinieneś napisać porządny serwis, żeby to czytelne było.

0

Na razie robię metodą małych kroków i zamiast tras chciałem wypisać punkty.
Zmieniłem XmlReader na:

public XmlReader
{
 public List<Punkt> GetXml()
        {
 
            XDocument xml = XDocument.Load("dane.xml");
            List<Punkt> punkt = (
                from punkt in xml.Elements("Punkt")
                select new Punkt(
                    int.Parse(punkt.Attribute("nrPunktu").Value),
                    punkt.Element("nazwaPunktu").Value,
		     int.Parse(punkt.Element("czasPobytu").Value)
                ).ToList<Punkt>();
            return punkt;
        }
}

Tylko że zwracana lista jest pusta. Gdzie popełniłem błąd?

0

Po 1: Nie występuje taki element jak: "punkt".
Po 2: Nie występuje taki element jak "czas".

Zwróć uwagę na wielkość liter i zapoznaj się z nazwami elementów.

0

Poprawione, to literówka była. W kodzie mam odpowiednie nazwy punktów i nie działa.

1

Tu:

from punkt in xml.Elements("Punkt")

Powinno być:

from
	punkt
in
	xml
	.Descendants()
	.Elements("Punkt")

Przeczytaj chociaż opis metody.

0

Ok, dzięki za pomoc. Teraz zostało mi tylko powalczyć żeby lista punktów była tylko z jednej trasy a nie ze wszystkich jak mam na tę chwilę.

0

Nie ogarniasz nic XML-a, prawda? Programistą na pewno też nie jesteś.

rozsierdza mnie to, że cwaniakujesz - najpierw mówisz, że chcesz to w jednej instrukcji, potem że nie ogarniasz jak się dostać do tras....
Nawet nie poświęcisz 5 minut na poczytaniu o XML.

Daj zlecenie na forum, to na pewno się ktoś odezwie.
Ja nie będę za Ciebie robił.

1 użytkowników online, w tym zalogowanych: 0, gości: 1