How to read XML with (CF)DictionaryMBS?

Hello,
How to read the xml content of this order with CFDictionaryMBS? ChatGPT always returns me lines of code that never work! Here is what he offers me:

Dim sh As New Shell
sh.Execute "system_profiler -xml SPHardwareDataType"
Dim output As String = sh.Result
Dim dict As CFDictionnaryMBS = CFDictionnaryMBS.CreateXMLDictionary(output)
Dim cpuInfo As Dictionary = dict.Value("CPU") //For example
Dim cpuName As String = cpuInfo.Value("_name") //For example

Thanks,

You may need:

NewCFObjectMBSFromXML(XMLdata as String) as CFObjectMBS

See
https://www.monkeybreadsoftware.net/global-newcfobjectmbsfromxml.shtml

the code leaves at the line: “if o isa CFDictionaryMBS then”, what should i put?

Var sh As New Shell
sh.Execute("/usr/sbin/system_profiler -xml SPHardwareDataType")
exit_code = sh.ExitCode
If exit_code = 0 Then
  Var s As String = sh.ReadAll
  if s <> "" then
    Var o as CFObjectMBS
    Var d As CFDictionaryMBS
    
    o=NewCFObjectMBSFromXML(NewCFBinaryDataMBSStr(s))
      if o <> nil then
      if o isa CFDictionaryMBS then //<--------End Sub here !!!
        d=CFDictionaryMBS(o)
        MsgBox CFStringMBS(d.Value(NewCFStringMBS("Key"))).str
      end if
    end if
    end
  End

Did you look in debugger?

o isa CFArrayMBS since the plist starts with an array.

Ok. But now I get the message “Illegal Cast Exception” : CFArrayMBS cannot be cast to CFDictionaryMBS…

if o <> nil then
  if o isa CFArrayMBS then
    d=CFDictionaryMBS(o) //<----Exception
    MsgBox CFStringMBS(d.Value(NewCFStringMBS("Key"))).str
  end if
end if

Yes, because you have to change that code to use CFArrayMBS instead of CFDictionaryMBS.

The example code assumes a CFDictionaryMBS, but that isn’t the case for your output.

Thanks. Finally, what syntax for the messagebox (Key and Value)?

Var d As CFArrayMBS 
o=NewCFObjectMBSFromXML(NewCFBinaryDataMBSStr(s))
if o <> nil then
  if o isa CFArrayMBS then
    d=CFArrayMBS(o)
    MsgBox CFStringMBS(d.Value(NewCFStringMBS("Key"))).str //<--- ???
  end if
end if

When I tried the examples online at MBS, I had an issue with this object
The examples show o.count - it was visible in the debugger, but not at runtime in code.
I gave up.

Is it me, but do these things have unnecessarily overcomplicated names and access methods?

Not all properties are debugger visible, but count should be visible.
You may need to cast to CFArrayMBS object for Xojo to show it.

So Leroy may need to write a loop to go over the entries, just like the sample here:
https://www.monkeybreadsoftware.net/class-cfarraymbs.shtml

Here is some example code:

Var sh As New Shell
sh.Execute("/usr/sbin/system_profiler -xml SPHardwareDataType")
Dim exit_code As Integer = sh.ExitCode
If exit_code = 0 Then
  Var s As String = sh.ReadAll
  If s <> "" Then
    Var o As CFObjectMBS = NewCFObjectMBSFromXML(s)
    If o IsA CFArrayMBS Then
      Dim a As CFArrayMBS = CFArrayMBS(o)
      If a.Count > 0 Then
        o = a.Item(0)
        If o IsA CFDictionaryMBS Then //<--------End Sub here !!!
          Dim d As CFDictionaryMBS = CFDictionaryMBS(o)
          MsgBox CFStringMBS(d.Value(NewCFStringMBS("_dataType"))).Str
          
          // now convert it to Xojo Dictionary
          Dim dic As Dictionary = d.Dictionary
          Dim properties As Dictionary = dic.Value("_properties")
          Break
          
        End If
      End If
    End
  End
End If

While we have a function to convert CFDictionaryMBS to regular dictionary, this may be missing for an array.

I’ll add it for next version with AsArrray function:

Var sh As New Shell
sh.Execute("/usr/sbin/system_profiler -xml SPHardwareDataType")
Dim exit_code As Integer = sh.ExitCode
If exit_code = 0 Then
  Var s As String = sh.ReadAll
  If s <> "" Then
    Var o As CFObjectMBS = NewCFObjectMBSFromXML(s)
    If o IsA CFArrayMBS Then
      Dim a As CFArrayMBS = CFArrayMBS(o)
      Dim values() As Variant = a.AsArray
      dim d as Dictionary = values(0)
      
      MsgBox d.Value("_dataType")
      
      // now convert it to Xojo Dictionary
      Dim properties As Dictionary = d.Value("_properties")
      Break
      
    End If
  End If
End If

Thanks @Christian_Schmitz , but I just wanted to retrieve the value of a key, passed as a parameter. The function returns me the string “SPHardwareDataType”! what interest ?

Please inspect the XML and see what values you can query.

SPHardwareDataType is just one of the values inside the dictionary and I picked it as an example.