C# XMLparsing

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
anojak
Inlägg: 223
Blev medlem: 4 oktober 2011, 12:20:55

C# XMLparsing

Inlägg av anojak »

Hej!

Någon gång i början av december började jag lite smått att försöka lära mig att programmera i C#. Har skrivit "kod" i Matlab och Arduino IDE innan så man kan inte säga att jag har någon erfarenhet eller tidiagre programmeringskunskaper direkt. I alla fall så fick jag en idé i förrgår med att försöka läsa ut data (=busstider) från SLs API och sedan presentera de på en skärm via en Raspberry Pi.

Men eftersom att jag som sagt knappt har programmerat innan så tänkte jag att jag börjar att skriva en konsolapplikation och det är där jag har fastnat. Har försökt att läsa på online och kolla på Youtube men blir inte klokare. Jag tror att felet ligger i att den inte hittar rätt i (ResponseOfDeparture/ResponseData..../...) men vet inte hur jag ska lösa det.

Jag bifogar en bild på XML-filen, och koden, ifrån programmet ska hämta datan.

All input som kan hjälpa mig framåt är uppskattad! Ber om ursäkt för mitt amatörmässiga (programmerings-)språk för att beskriva problemet :wink:

Kod: Markera allt

using System;
using System.Text;
using System.Xml;

namespace Reseplanerare
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("http://api.sl.se/api2/realtimedepartures.xml?key=MIN-API-NYCKEL&siteid=7074&timewindow=60");
            XmlNodeList List = xmlDoc.SelectNodes("ResponseOfDepartues/ResponseData/Buses/Bus");
            if (List != null) 
            {
                foreach (XmlNode N in List)
               {
                   string Destination = N["Destination"].InnerText;
                   string Time = N["DisplayTime"].InnerText;
                   Console.WriteLine(Destination, " ", Time, " min");
               }
            }
               
            else
            {
                Console.WriteLine("Datan kunde inte hämtas"); 
            }
            Console.ReadKey();
        }
    }
}
SL2.JPG
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C# XMLparsing

Inlägg av sodjan »

Det ska alltså köras på en RasPi?
Python har den del lättanvända verktyg som t.ex Suds för att läsa SOAP/XML källor.
https://fedorahosted.org/suds/ Jag använder det till att köra Traderas API.
Inte på en RasPi men från Python i alla fall...

Den där strukturen ser ganska enkel ut och vore inget problem att läsa.
Zeela
Inlägg: 176
Blev medlem: 28 augusti 2008, 11:23:49
Ort: Åtvidaberg
Kontakt:

Re: C# XMLparsing

Inlägg av Zeela »

Har du XML:en som fil? Så kan jag kika lite på det...
Och se om du gör nåt uppenbart tokigt. :)
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C# XMLparsing

Inlägg av sodjan »

Behövs det inloggning för att köra API't?
anojak
Inlägg: 223
Blev medlem: 4 oktober 2011, 12:20:55

Re: C# XMLparsing

Inlägg av anojak »

sodjan:
Anledningen till att jag vill köra med C# är för att jag tycker att det är nog så jobbigt att lära mig det mitt i bland stuider, jobb osv... Men python står näst på tur på "saker-jag-vill-lära-mig-innan-allt-blir-svart-listan". Sparar länken så jag kan kika på det då. Och som svar på din andra fråga så är svaret nej - ingen inloggning krävs. :tumupp:

Zeela:
Tack för att du erbjuder dig att titta på koden. Nu har jag fått en annan kod att fungera men om du vill kolla på den gamla så kan jag ska fixa fram en XML-fil men hinner nog inte riktigt idag, ska iväg på galej om <45 min. Jag är faktiskt intresserad av varför den inte fungerar.

Övriga:
Var borta på middag hela kvällen igår och eftersom att jag var ganska pigg när jag kom hem vid 01:00 så startade jag datorn och fortsatte att felsöka/arbeta med koden. Jag följde Microsofts Tutorial till punkt och pricka(CTRL+C CTRL+V) och efter en stunds funderande om vad som egentligen händer så lyckades jag presentera lite data på skärmen! Koden är varken snygg och jag tror inte att den är effektiv men vad gör det kände jag :D

Ny kod för konsolapplikation:

Kod: Markera allt

using System;
using System.Xml;

namespace ReadXMLfromURL
{
    class Class1
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Ange SiteID, xxxx, för hållplats: ");
            Console.WriteLine("Slussen: 9192, Huddinge: 9527, Vänhemsvägen: 7074");

            string SiteID = Console.ReadLine(); 
            
            String URLString1 = "http://api.sl.se/api2/realtimedepartures.xml?key=MINAPINYCKEL&siteid=";
            String URLString2 = "&timewindow=60";
            String URLString = URLString1 + SiteID + URLString2;
            XmlTextReader reader = new XmlTextReader(URLString);
            
            int destination = 1;
            int time = 1;
            int clock = 1;
            int Line = 1;
            int Buses = 1;
            int Trains = 1;
            int Metros = 1;

            

            while (reader.Read())
            {
               
                
                switch (reader.NodeType)
                {

                    case XmlNodeType.Text: //Display the text in each element

                        if (Metros == 0)
                        {
                            Console.WriteLine(" ");
                            Console.WriteLine("Tunnelbana:");
                            Metros = 1;

                        }
                        if (Buses == 0)
                        {
                            Console.WriteLine(" ");
                            Console.WriteLine("Buss:");
                            Buses = 1;

                        }
                        if (Trains == 0)
                        {
                            Console.WriteLine(" ");
                            Console.WriteLine("Pendeltåg:");
                            Trains = 1;

                        }
                        if (Line == 0)
                        {
                            Console.Write("Linje " + reader.Value);
                            Line = 1;

                        }
                        if (destination == 0)
                        {
                            Console.Write(" mot " + reader.Value + " ");
                            destination = 1;
                            
                        }
                        if (time == 0)
                        {
                            Console.WriteLine(reader.Value);
                            time = 1;
                        }
                        if (clock == 0)
                         {
                             string clock2 = Convert.ToString(reader.Value);
                             var s = @clock2;
                             var r = s.Substring(s.IndexOf(@"T") + 1);
                             Console.WriteLine("Senast uppdaterad: " + r);
                             clock = 1;
                         }
                            
                        break; 
                 
                    case XmlNodeType.Element: // The node is an element.
                        if (reader.Name == "Destination")
                        { destination = 0; }
                        if (reader.Name == "DisplayTime")
                        { time = 0; }
                        if (reader.Name == "LatestUpdate")
                        { clock = 0; }
                        if (reader.Name == "LineNumber")
                        { Line = 0; }
                        if (reader.Name == "Buses")
                        { Buses = 0; }
                        if (reader.Name == "Trains")
                        { Trains = 0; }
                        if (reader.Name == "Metros")
                        { Metros = 0; }

                        break;

                }
            }
            Console.ReadKey();
        }
    }
}
reseplanerare6.JPG
Idag på eftermiddagen fortsatte jag men att skriva om den till en Windows Form Application:

Kod för Windows Form Application:

Kod: Markera allt

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

      

        private void button1_Click(object sender, EventArgs e)
        {
            string SiteID = "7074";
            
            String URLString1 = "http://api.sl.se/api2/realtimedepartures.xml?key=MINAPINYCKEL&siteid=";
            String URLString2 = "&timewindow=60";
            String URLString = URLString1 + SiteID + URLString2;
            XmlTextReader reader = new XmlTextReader(URLString);
            
            int destination = 1;
            int time = 1;
            int Line = 1;
           
            string Linje = " ";
            string mot = " ";
            string tid = " ";
            int clock = 1;
            int a = 0;

            

            while (reader.Read())
            {
               
                
                switch (reader.NodeType)
                {

                    case XmlNodeType.Text: 
      
                        if (Line == 0)
                        {
                            Linje = "Linje " + reader.Value;
                            Line = 1;
                            a++;
                       


                        }
                        if (destination == 0)
                        {
                            mot = (" mot " + reader.Value + " ");
                            destination = 1;
                            
                        }
                        if (time == 0)
                        {
                            tid = (reader.Value);
                            time = 1;
                        }
                        if (clock == 0)
                        {
                            string clock2 = Convert.ToString(reader.Value);
                            var s = @clock2;
                            var r = s.Substring(s.IndexOf(@"T") + 1);
                            label3.Text = (r);
                            clock = 1;
                        }
                        if (a == 1)
                            label1.Text = Linje + mot + tid;
                        if (a == 2)
                            label5.Text = Linje + mot + tid;
                        if (a == 3)
                            label6.Text = Linje + mot + tid;
         break; 
                    case XmlNodeType.Element: 
                        if (reader.Name == "Destination")
                        { destination = 0; }
                        if (reader.Name == "DisplayTime")
                        { time = 0; }
                        if (reader.Name == "LineNumber")
                        { Line = 0; }
                        if (reader.Name == "LatestUpdate")
                        { clock = 0; }


                        break;

                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


      
    }
}
Reseplanerare5.JPG
Båda koderna innehåller säkert mycket onödigt, konstiga variabelnamn och blanksteg etc så det får bli morgondagens projekt att städa upp och effektivisera. Ikväll ska jag bara njuta av att det fungerar! :bravo: :D :bravo: Sen ska jag fixa till UI på senaste koden och lägga till auto-update, möjlighet att välja station etc. Det blir nog en projekttråd snart då jag ska köra koden, på något sätt, på en hallonpaj med tillhörande skärm i en snygg låda... Ska försöka få till så den presenterar avgångarna efter den som går först också. Och möjlighet att välja vilket färdslag, buss/båt/tåg etc, man vill presentera. Kanske möjlighet att presentera enstaka linjer också. Vi får se hur det blir helt enkelt, det blir väl ytterligare ett never ending project.... :D



Emil
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C# XMLparsing

Inlägg av sodjan »

> Sparar länken så jag kan kika på det då.

Länken gick alltså till "suds" vilket är ett SOAP tillägg till Python.
Men jag ser nu att det ju inte var ett SOAP/WS API utan "bara"
en vanlig URL som direkt ger ett svar tillbaka. Så glöm länken... :-)
anojak
Inlägg: 223
Blev medlem: 4 oktober 2011, 12:20:55

Re: C# XMLparsing

Inlägg av anojak »

Aha så var det. Jaja jag sparar den ändå, kanske bra och intressant att läsa och använda när man är mer inne i Python.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C# XMLparsing

Inlägg av sodjan »

Det finns en del olika verktyg för att enkelt hantera XML
strukturer i Python. Här är några exempel:
http://www.crummy.com/software/BeautifulSoup/
https://pypi.python.org/pypi/PySimpleXML/1.0
http://xmlsoft.org/python.html

Jag har ingen uppfattning alls om deras kvalitet eller så,
jag såg bara att de är inbyggda i min Python dist.
Användarvisningsbild
maDa
Inlägg: 4076
Blev medlem: 11 november 2005, 22:13:16
Ort: Malmö
Kontakt:

Re: C# XMLparsing

Inlägg av maDa »

Ska du skapa saker för RPi och embedded så är C# ett ganska dåligt val.

Python är utmärkt för mycket. Här hämtar jag lite vädersaker från YR.no.

Kod: Markera allt

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import requests
import xml.etree.ElementTree as ET

API_URL='http://www.yr.no/place/Sweden/Scania/Malmö/forecast.xml'

root = ET.fromstring(requests.get(API_URL).content)
data = root.findall("./forecast/tabular/time")[0]
temp = data.findall('temperature')[0].attrib
wind = data.findall('windSpeed')[0].attrib

print "Temperature:", temp['value'], temp['unit']
print "Wind:", wind['mps'], "mps (" + wind['name'] + ")"
När de kommer till GUI så tycker jag alltid man ska försöka göra det webbaserat, för det fungerar överallt. Annars är WxPython rätt enkelt att komma igång med.
XorXaX
Inlägg: 409
Blev medlem: 27 maj 2004, 09:44:16

Re: C# XMLparsing

Inlägg av XorXaX »

C# fungerar alldeles utmärkt på RPi, så länge man håller sig till konsolapplikationer. Ska man göra GUI blir det genast jobbigt och t.ex. Python med Tk är att föredra.

Jag har gjort en liknande applikation, fast i webbformat (ASP.NET C#); http://home.haksberg.net/ så det går att se enkelt i telefonen när det är dags att röra sig mot hållplatsen :)
Skriv svar