none
JSON oder XML-String auswerten RRS feed

  • Frage

  • Hallo,

    ich habe zuhause einen FHEM Hausautomatisierungsserver stehen. Dieser gibt mir den Status von Lampen in der JSON oder XML Formatierung aus. Trotz langem suchen im Netz, habe ich immer noch keine Ahnung, wie ich eins der beiden auswerte.

    Ich hoffe ihr könnt mir weiterhelfen.

    Hier mal die Ausgaben:

    XML:

    <FHZINFO>
    	<IT_LIST>
    		<IT name="Lampe" state="off" sets="off:noArg on:noArg  on-for-timer on-till off-for-timer on-till-overnight blink toggle off-till-overnight intervals off-till" attrs="verbose:0,1,2,3,4,5 room group comment alias eventMap userReadings IODev ITfrequency ITrepetition switch_rfmode:1,0 do_not_notify:1,0 ignore:0,1 protocol:V1,V3,HE_EU,HE800 unit group dummy:1,0 event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat loglevel:0,1,2,3,4,5,6 model:itdimmer,itremote,itswitch cmdIcon devStateIcon devStateStyle icon sortby webCmd widgetOverride yaf_1 yaf_3 yaf_4 yaf_5 yaf_6 yaf_7 yaf_8 userattr">
    			<INT key="00" value="10"/>
    			<INT key="CFGFN" value="/opt/fhem/FHEM/Wohnzimmer.cfg"/>
    			<INT key="DEF" value="000FFFFF01 01 10"/>
    			<INT key="NAME" value="Lampe"/>
    			<INT key="NR" value="62"/>
    			<INT key="STATE" value="off"/>
    			<INT key="TYPE" value="IT"/>
    			<INT key="XMIT" value="000fffff01"/>
    			<INT key="XMITdimdown" value="00"/>
    			<INT key="XMITdimup" value="00"/>
    			<INT key="XMITon" value="01"/>
    			<INT key="IODev" value="CUL433"/>
    			<ATTR key="IODev" value="CUL433"/>
    			<ATTR key="group" value="Beleuchtung"/>
    			<ATTR key="room" value="Wohnzimmer"/>
    			<ATTR key="sortby" value="01"/>
    			<ATTR key="yaf_1" value="id=3,fhemname=Lampe,y_pos=223,x_pos=546,name=iteasylamp,"/>
    			<STATE key="protocol" value="V1" measured="2015-03-27 19:11:45"/>
    			<STATE key="state" value="off" measured="2015-10-13 07:30:00"/>
    		</IT>
    	</IT_LIST>
    </FHZINFO>
    
    


    JSON:

    {
      "ResultSet": {
        "Results": {
          "00": "10",
          "ATTRIBUTES": {
            "IODev": "CUL433",
            "group": "Beleuchtung",
            "room": "Wohnzimmer",
            "sortby": "01",
            "yaf_1": "id=3,fhemname=Lampe,y_pos=223,x_pos=546,name=iteasylamp,"
          },
          "CFGFN": "/opt/fhem/FHEM/Wohnzimmer.cfg",
          "CODE": {
            "1": "000fffff01"
          },
          "DEF": "000FFFFF01 01 10",
          "IODev": "CUL433",
          "NAME": "Lampe",
          "NR": "62",
          "READINGS": {
            "protocol": {
              "TIME": "2015-03-27 19:11:45",
              "VAL": "V1"
            },
            "state": {
              "TIME": "2015-10-13 07:30:00",
              "VAL": "off"
            }
          },
          "STATE": "off",
          "TYPE": "IT",
          "XMIT": "000fffff01",
          "XMITdimdown": "00",
          "XMITdimup": "00",
          "XMITon": "01"
        }
      }
    }
    

    Vielen Dank im voraus

    arokh12

    Dienstag, 13. Oktober 2015 14:50

Antworten

  • Hi,

    das, was da steht, entspricht nicht dem Aufbau deiner Klasse FHEM_Test, sondern eher dem Aufbau von RootObject. Probier es daher mal hiermit:

    RootObject m = JsonConvert.DeserializeObject<RootObject>(responseBodyAsText);

    Allerdings hat RootObject keine Eigenschaft "Name", daher wird die nächste Zeile dann auch als Fehler markiert. Du musst dann eher die Results Auflistung durchlaufen und die bspw. vom ersten Element die Eigenschaft Name abgreifen, bspw. über:

    Status.Text = m.Results[ 0 ].Name;

    Das obige ist ein Direktzugriff auf das erste Arrayelement in m.Results, wenn Results leer ist, wird das aber auch fehlschlagen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort vorgeschlagen Stefan FalzModerator Samstag, 17. Oktober 2015 21:18
    • Als Antwort markiert arokh12 Samstag, 24. Oktober 2015 18:33
    Samstag, 17. Oktober 2015 13:37
    Moderator

Alle Antworten

  • Hallo,
    z.B. mit Linq to XML: https://msdn.microsoft.com/de-de/library/bb387098.aspx


    Viele Grüße Holger M. Rößler

    Dienstag, 13. Oktober 2015 14:54
  • Hi,

    JSON.NET wäre für die JSON Verarbeitung mein Favorit. Funktioniert auch mit Windows Phone, ...

      http://www.newtonsoft.com/json


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 13. Oktober 2015 15:15
    Moderator
  • Hallo,

    ich ahbe jetzt mit beidem rumprobiert. Und ich bekomme es nicht hin. Kann mir einer eine Anleitung geben?

    Die Beispiele auf der seite gehen nicht.

    arokh12

    Freitag, 16. Oktober 2015 15:28
  • Hi,

    poste doch mal bitte den Code, mit dem Du es versucht hast.

    Die Beispiele auf der Seite funktionieren grundsätzlich schon, daher denke ich eher, dass Du etwas vergessen hast.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 16. Oktober 2015 15:36
    Moderator
  • Hi,

    poste doch mal bitte den Code, mit dem Du es versucht hast.

    Die Beispiele auf der Seite funktionieren grundsätzlich schon, daher denke ich eher, dass Du etwas vergessen hast.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Hier ist der Code:

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using Windows.Data.Json; using System.Runtime.Serialization.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System.Net; // Die Elementvorlage "Leere Seite" ist unter http://go.microsoft.com/fwlink/?LinkId=391641 dokumentiert. namespace FHEM { /// <summary> /// Eine leere Seite, die eigenständig verwendet werden kann oder auf die innerhalb eines Rahmens navigiert werden kann. /// </summary> public sealed partial class MainPage : Page { HttpClient client = new HttpClient(); HttpResponseMessage response = new HttpResponseMessage(); private string Link = "http://XXX:XXX/fhem?cmd=jsonlist2 Lampe&XHR=1"; public MainPage() { this.InitializeComponent(); this.NavigationCacheMode = NavigationCacheMode.Required; // Senden string _auth = string.Format("{0}:{1}", "XXX", "XXX"); string _enc = Convert.ToBase64String(Encoding.UTF8.GetBytes(_auth)); string _basic = string.Format("{0} {1}", "Basic", _enc); client.DefaultRequestHeaders.Add("Authorization", _basic); } private async void Button_Click(object sender, RoutedEventArgs e) { Status.Text = "Test if URI is valid"; Uri resourceUri; if (!Uri.TryCreate(Link, UriKind.Absolute, out resourceUri)) { Status.Text = "Invalid URI, please re-enter a valid URI"; return; } if (resourceUri.Scheme != "http" && resourceUri.Scheme != "https") { Status.Text = "Only 'http' and 'https' schemes supported. Please re-enter URI"; return; } string responseBodyAsText; Status.Text = "Waiting for response ..."; var json_data = string.Empty; try { response = await client.GetAsync(Link); response.EnsureSuccessStatusCode(); responseBodyAsText = await response.Content.ReadAsStringAsync(); } catch (Exception ex) { // Need to convert int HResult to hex string Status.Text = "Error = " + ex.HResult.ToString("X") + " Message: " + ex.Message; responseBodyAsText = ""; } Status.Text = response.StatusCode + " " + response.ReasonPhrase; // Format the HTTP response to display better responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine); Status.Text = responseBodyAsText; Status.Text = ""; FHEM_Test m = JsonConvert.DeserializeObject<FHEM_Test>(responseBodyAsText); Status.Text = m.NAME; } } public class FHEM_Test { public string __invalid_name__00 { get; set; } public string CFGFN { get; set; } public string DEF { get; set; } public string NAME { get; set; } public string NR { get; set; } public string STATE { get; set; } public string TYPE { get; set; } public string XMIT { get; set; } public string XMITdimdown { get; set; } public string XMITdimup { get; set; } public string XMITon { get; set; } } public class Protocol { public string Value { get; set; } public string Time { get; set; } } public class State { public string Value { get; set; } public string Time { get; set; } } public class Readings { public Protocol protocol { get; set; } public State state { get; set; } } public class Attributes { public string IODev { get; set; } public string group { get; set; } public string room { get; set; } public string sortby { get; set; } public string yaf_1 { get; set; } } public class Result { public string Name { get; set; } public string PossibleSets { get; set; } public string PossibleAttrs { get; set; } public FHEM_Test Internals { get; set; } public Readings Readings { get; set; } public Attributes Attributes { get; set; } } public class RootObject { public string Arg { get; set; } public List<Result> Results { get; set; } public int totalResultsReturned { get; set; } }

    }

    Ich habe hier mal den Fehlercode:

    In System.ArgumentNullException ist eine Ausnahme vom Typ "mscorlib.ni.dll" aufgetreten, doch wurde diese im Benutzercode nicht verarbeitet.
    
    Zusätzliche Informationen: Value cannot be null.
    
    Falls ein Handler für diese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden.

    Danke schonmal

    arokh12

    Freitag, 16. Oktober 2015 15:44
  • Hi,

    in welcher Zeile tritt der Fehler auf? Poste bitte den gesamten Stacktrace, ggfs. im Windows Ereignisprotokoll schauen, ob es dort Details zum Fehler gibt.

    Was genau steht in responseBodyAsString?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 16. Oktober 2015 16:06
    Moderator
  • Der Fehler tritt in dieser Zeile auf:

                Status.Text = m.NAME;

    Der Inhalt von responseBodyAsText sieht wie folgt aus:

    "{\n  \"Arg\":\"Lampe\",\n  \"Results\": [\n  {\n    \"Name\":\"Lampe\",\n    \"PossibleSets\":\"off:noArg on:noArg  on-for-timer on-till off-for-timer on-till-overnight blink toggle off-till-overnight intervals off-till\",\n    \"PossibleAttrs\":\"verbose:0,1,2,3,4,5 room group comment alias eventMap userReadings IODev ITfrequency ITrepetition switch_rfmode:1,0 do_not_notify:1,0 ignore:0,1 protocol:V1,V3,HE_EU,HE800 unit group dummy:1,0 event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat loglevel:0,1,2,3,4,5,6 model:itdimmer,itremote,itswitch cmdIcon devStateIcon devStateStyle icon sortby webCmd widgetOverride yaf_1 yaf_3 yaf_4 yaf_5 yaf_6 yaf_7 yaf_8 userattr\",\n    \"Internals\": {\n      \"00\": \"10\",\n      \"CFGFN\": \"/opt/fhem/FHEM/Wohnzimmer.cfg\",\n      \"DEF\": \"000FFFFF01 01 10\",\n      \"NAME\": \"Lampe\",\n      \"NR\": \"62\",\n      \"STATE\": \"off\",\n      \"TYPE\": \"IT\",\n      \"XMIT\": \"000fffff01\",\n      \"XMITdimdown\": \"00\",\n      \"XMITdimup\": \"00\",\n      \"XMITon\": \"01\"\n    },\n    \"Readings\": {\n      \"protocol\": { \"Value\":\"V1\", \"Time\":\"2015-03-27 19:11:45\" },\n      \"state\": { \"Value\":\"off\", \"Time\":\"2015-10-17 07:30:00\" }\n    },\n    \"Attributes\": {\n      \"IODev\": \"CUL433\",\n      \"group\": \"Beleuchtung\",\n      \"room\": \"Wohnzimmer\",\n      \"sortby\": \"01\",\n      \"yaf_1\": \"id=3,fhemname=Lampe,y_pos=223,x_pos=546,name=iteasylamp,\"\n    }\n  }  ],\n  \"totalResultsReturned\":1\n}\n\n"

    arokh12


    Samstag, 17. Oktober 2015 13:12
  • Hi,

    das, was da steht, entspricht nicht dem Aufbau deiner Klasse FHEM_Test, sondern eher dem Aufbau von RootObject. Probier es daher mal hiermit:

    RootObject m = JsonConvert.DeserializeObject<RootObject>(responseBodyAsText);

    Allerdings hat RootObject keine Eigenschaft "Name", daher wird die nächste Zeile dann auch als Fehler markiert. Du musst dann eher die Results Auflistung durchlaufen und die bspw. vom ersten Element die Eigenschaft Name abgreifen, bspw. über:

    Status.Text = m.Results[ 0 ].Name;

    Das obige ist ein Direktzugriff auf das erste Arrayelement in m.Results, wenn Results leer ist, wird das aber auch fehlschlagen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    • Als Antwort vorgeschlagen Stefan FalzModerator Samstag, 17. Oktober 2015 21:18
    • Als Antwort markiert arokh12 Samstag, 24. Oktober 2015 18:33
    Samstag, 17. Oktober 2015 13:37
    Moderator
  • Hi,

    das, was da steht, entspricht nicht dem Aufbau deiner Klasse FHEM_Test, sondern eher dem Aufbau von RootObject. Probier es daher mal hiermit:

    RootObject m = JsonConvert.DeserializeObject<RootObject>(responseBodyAsText);

    Allerdings hat RootObject keine Eigenschaft "Name", daher wird die nächste Zeile dann auch als Fehler markiert. Du musst dann eher die Results Auflistung durchlaufen und die bspw. vom ersten Element die Eigenschaft Name abgreifen, bspw. über:

    Status.Text = m.Results[ 0 ].Name;

    Das obige ist ein Direktzugriff auf das erste Arrayelement in m.Results, wenn Results leer ist, wird das aber auch fehlschlagen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Alles klar, danke funktioniert perfekt.

    arokh12

    Samstag, 17. Oktober 2015 13:46
  • Hi,

    das, was da steht, entspricht nicht dem Aufbau deiner Klasse FHEM_Test, sondern eher dem Aufbau von RootObject. Probier es daher mal hiermit:

    RootObject m = JsonConvert.DeserializeObject<RootObject>(responseBodyAsText);

    Allerdings hat RootObject keine Eigenschaft "Name", daher wird die nächste Zeile dann auch als Fehler markiert. Du musst dann eher die Results Auflistung durchlaufen und die bspw. vom ersten Element die Eigenschaft Name abgreifen, bspw. über:

    Status.Text = m.Results[ 0 ].Name;

    Das obige ist ein Direktzugriff auf das erste Arrayelement in m.Results, wenn Results leer ist, wird das aber auch fehlschlagen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Ein Problem ist doch leider aufgetaucht.

    Wenn das Programm ausgeführt wird, funktioniert es perfekt. Ändere ich aber den Namen des Devices, und ich führe es erneut aus, dann bleibt der alte Name.

    Woran liegt das und wie kann ich das beheben?

    arokh12

    Samstag, 17. Oktober 2015 14:05
  • Hi,

    keine Ahnung^^

    Du musst schon schauen, was genau in deinem JSON String ankommt. Wenn dort immer noch der alte Name steht, hast Du wahrscheinlich an der falschen Stelle geändert.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Samstag, 17. Oktober 2015 18:26
    Moderator
  • Hi,

    keine Ahnung^^

    Du musst schon schauen, was genau in deinem JSON String ankommt. Wenn dort immer noch der alte Name steht, hast Du wahrscheinlich an der falschen Stelle geändert.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    im JSON String kommt der neue Name an. Wird aber wohl nicht verarbeitet. Gucke mir morgen das Programm nochmal an.

    arokh12

    Samstag, 17. Oktober 2015 19:00
  • Hi,

    ok, prima.

    Es wäre hilfreich, wenn Du diesen Thread abschließen würdest. Die Funktion "Abstimmen" und "Als Antwort markieren" helfen anderen Usern dabei, die hilfreichsten Antworten in einem Thread direkt zu erkennen.

    Neue Fragen bitte jeweils in einem neuen Thread stellen, da es ansonsten für alle Beteiligten sehr unübersichtlich  wird.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Samstag, 17. Oktober 2015 19:06
    Moderator