0

I need some kind of structure to add, remove and read (get) some values for some settings.

In PHP I would create sth. like:

["root"]["Audio"]["DuplexMode"] = full;
["root"]["AudioSource"]["A0"]["AudioEncoding"] = g711;
["root"]["Network"]["Interface"]["I0"]["Active"]["MACAddress"] = 00:40:8C:9A:1F:56;

and access it like this:

DuplexMode = ["root"]["Audio"]["DuplexMode"];
AudioEncoding = ["root"]["AudioSource"]["A0"]["AudioEncoding"];
MACAddress = ["root"]["Network"]["Interface"]["I0"]["Active"]["MACAddress"];
...

or

foreach (x in ["root"]["AudioSource"]["A0"]) {...}

should give me all the settings under root.AudioSource.A0.

But this seams not to be possible in C#. (Or at least I don't know how...)

Here is the list of settings which is a quite long string I get from a network-camera. (There are not always the same settings for each device.)

root.Audio.DuplexMode=full
root.Audio.MaxListeners=20
root.Audio.ReceiverBuffer=120
root.Audio.ReceiverTimeout=1000
root.Audio.NbrOfConfigs=1
root.Audio.DSCP=0
root.Audio.A0.Enabled=yes
root.Audio.A0.HTTPMessageType=singlepart
root.Audio.A0.Name=
root.Audio.A0.Source=0
root.Audio.A0.AlarmLevel=50
root.Audio.A0.AlarmResolution=50
root.Audio.A0.AlarmLowLimit=10
root.Audio.A0.AlarmHighLimit=6500
root.AudioSource.NbrOfSources=1
root.AudioSource.A0.Name=Audio
root.AudioSource.A0.AudioEncoding=g711
root.AudioSource.A0.InputType=mic
root.AudioSource.A0.InputGain=auto
root.AudioSource.A0.OutputGain=0
root.AudioSource.A0.SampleRate=8000
root.AudioSource.A0.HWSampleRate=16000
root.AudioSource.A0.BitRate=64000
root.AudioSource.A0.CustomReg=
root.AudioSource.A0.AudioSupport=yes
root.Bandwidth.Limit=0
root.Brand.Brand=AXIS
root.Brand.ProdFullName=AXIS M1031-W Network Camera
root.Brand.ProdShortName=AXIS M1031-W
root.Brand.ProdNbr=M1031-W
root.Brand.ProdType=Network Camera
root.Brand.WebURL=http://www.axis.com/
root.Event.E0.Name=NightLight
root.Event.E0.Type=T
root.Event.E0.Enabled=yes
root.Event.E0.Priority=1
root.Event.E0.Image=0
root.Event.E0.HWInputs=1
root.Event.E0.SWInput=
root.Event.E0.Weekdays=1111111
root.Event.E0.Starttime=19:00
root.Event.E0.Duration=12:00
root.Event.E0.MinimumTriggerInterval=00:00:00
root.Event.E0.MinimumTriggerTimePeriod=00:00:00
root.Event.E0.ImageURLSettingsEnabled=no
root.Event.E0.ImageURLSettings=
root.Event.E0.IncludePreTrigger=no
root.Event.E0.PreTriggerDuration=
root.Event.E0.PreTriggerDurationUnit=s
root.Event.E0.IncludePostTrigger=no
root.Event.E0.PostTriggerDuration=
root.Event.E0.PostTriggerDurationUnit=s
root.Event.E0.IncludeBestEffort=no
root.Event.E0.BestEffortDuration=0
root.Event.E0.BestEffortDurationUnit=s
root.Event.E0.IncludeAudio=no
root.Event.E0.MPEGPreTriggerDuration=5
root.Event.E0.MPEGPostTriggerDuration=2
root.Event.E0.VideoFormat=
root.Event.E0.FrameRate=
root.Event.E0.Actions.A0.Type=N
root.Event.E0.Actions.A0.Protocol=Light
root.Event.E0.Actions.A0.Order=0
root.Event.E0.Actions.A0.Light=1
root.Event.E0.Actions.A0.Activate=100
root.Event.E0.Actions.A0.Inactivate=-0
root.Event.E0.Actions.A0.Duration=30
root.Event.E0.Actions.A0.Unit=s
root.HTTPS.Certificate=none
root.HTTPS.Enabled=no
root.HTTPS.Port=443
root.Image.TriggerDataEnabled=yes
root.Image.ReferrersEnabled=no
root.Image.Referrers=
root.Image.MaxViewers=20
root.Image.MotionDetection=yes
root.Image.NbrOfConfigs=1
root.Image.RFCCompliantMultipartEnabled=yes
root.Image.PrivacyMaskType=mask_windows
root.Image.OverlayPath=/etc/overlays/axis(128x44).ovl
root.Image.DateFormat=YYYY-MM-DD
root.Image.OwnDateFormat=%F
root.Image.OwnDateFormatEnabled=no
root.Image.TimeFormat=24
root.Image.OwnTimeFormat=%T
root.Image.OwnTimeFormatEnabled=no
root.Image.TimeResolution=1
root.Image.I0.Name=
root.Image.I0.Source=0
root.Image.I0.Appearance.Resolution=640x480
root.Image.I0.Appearance.Compression=30
root.Image.I0.Appearance.Rotation=0
root.Image.I0.Appearance.MirrorEnabled=no
root.Image.I0.Appearance.ColorEnabled=yes
root.Image.I0.MPEG.ConfigHeaderInterval=1
root.Image.I0.MPEG.UserDataEnabled=yes
root.Image.I0.MPEG.UserDataInterval=1
root.Image.I0.MPEG.ICount=1
root.Image.I0.MPEG.PCount=14
root.Image.I0.MPEG.Complexity=50
root.Image.I0.MPEG.ResyncMarkerEnabled=yes
root.Image.I0.MPEG.H264.PSEnabled=no
root.Image.I0.Overlay.Enabled=no
root.Image.I0.Overlay.XPos=0
root.Image.I0.Overlay.YPos=0
root.Image.I0.Overlay.MaskWindows.Color=black
root.Image.I0.Overlay.MaskWindows.M0.Enabled=no
root.Image.I0.Overlay.MaskWindows.M0.XPos=303
root.Image.I0.Overlay.MaskWindows.M0.YPos=2
root.Image.I0.Overlay.MaskWindows.M0.Width=160
root.Image.I0.Overlay.MaskWindows.M0.Height=48
root.Image.I0.Overlay.MaskWindows.M0.Name=Mask%200
root.Image.I0.Overlay.MaskWindows.M1.Enabled=no
root.Image.I0.Overlay.MaskWindows.M1.XPos=124
root.Image.I0.Overlay.MaskWindows.M1.YPos=4
root.Image.I0.Overlay.MaskWindows.M1.Width=148
root.Image.I0.Overlay.MaskWindows.M1.Height=56
root.Image.I0.Overlay.MaskWindows.M1.Name=Mask%201
root.Image.I0.Overlay.MaskWindows.M2.Enabled=no
root.Image.I0.Overlay.MaskWindows.M2.XPos=583
root.Image.I0.Overlay.MaskWindows.M2.YPos=52
root.Image.I0.Overlay.MaskWindows.M2.Width=54
root.Image.I0.Overlay.MaskWindows.M2.Height=113
root.Image.I0.Overlay.MaskWindows.M2.Name=Mask%202
root.Image.I0.RateControl.Mode=vbr
root.Image.I0.RateControl.Priority=framerate
root.Image.I0.RateControl.TargetBitrate=0
root.Image.I0.RateControl.MaxFPS=30
root.Image.I0.RateControl.MinFPS=1
root.Image.I0.RateControl.MaxCompression=100
root.Image.I0.RateControl.MinCompression=0
root.Image.I0.RateControl.MaxBitrate=0
root.Image.I0.SizeControl.MaxFrameSize=0
root.Image.I0.SizeControl.DiffFrameSize=0
root.Image.I0.Stream.Duration=0
root.Image.I0.Stream.NbrOfFrames=0
root.Image.I0.Stream.FPS=15
root.Image.I0.Text.DateEnabled=no
root.Image.I0.Text.ClockEnabled=no
root.Image.I0.Text.TextEnabled=no
root.Image.I0.Text.String=ET1
root.Image.I0.Text.Position=top
root.Image.I0.TriggerData.IOEnabled=yes
root.Image.I0.TriggerData.AudioEnabled=yes
root.Image.I0.TriggerData.TamperingEnabled=yes
root.Image.I0.TriggerData.MotionDetectionEnabled=yes
root.Image.I0.TriggerData.MotionLevelEnabled=no
root.Image.I0.TriggerData.UserTriggers=
root.ImageSource.NbrOfSources=1
root.ImageSource.MotionDetection=no
root.ImageSource.I0.Name=Camera
root.ImageSource.I0.Sensor.WhiteBalance=auto
root.ImageSource.I0.Sensor.Exposure=flickerfree50
root.ImageSource.I0.Sensor.MaxExposureTime=10000
root.ImageSource.I0.Sensor.MinExposureTime=10000
root.ImageSource.I0.Sensor.MaxGain=100
root.ImageSource.I0.Sensor.MinGain=0
root.ImageSource.I0.Sensor.ExposureValue=59
root.ImageSource.I0.Sensor.ExposurePriority=50
root.ImageSource.I0.Sensor.ColorDesaturation=100
root.ImageSource.I0.Sensor.Brightness=51
root.ImageSource.I0.Sensor.Contrast=56
root.ImageSource.I0.Sensor.ColorLevel=60
root.ImageSource.I0.Sensor.Sharpness=64
root.ImageSource.I0.Sensor.BacklightCompensation=yes
root.ImageSource.I0.Sensor.DynamicPixelCorrection=yes
root.ImageSource.I0.Sensor.AspectRatio=
root.ImageSource.I0.Sensor.ExposureWindow=auto
root.ImageSource.I0.Sensor.CustomExposureWindow.Weight=100
root.Input.NbrOfInputs=1
root.IOPort.I0.Configurable=no
root.IOPort.I0.Direction=input
root.IOPort.I0.Input.Name=PIR sensor
root.IOPort.I0.Input.Trig=closed
root.Layout.DefaultVideoFormat=mjpeg
root.Layout.ShowVideoFormatDropDown=yes
root.Layout.DefaultStreamProfile=
root.Layout.ViewerIE=activex
root.Layout.ViewerOther=spush
root.Layout.SetupLinkEnabled=yes
root.Layout.SnapshotEnabled=no
root.Layout.PlainConfigEnabled=no
root.Layout.ShowAMCToolbar=yes
root.Layout.AMCRecordMedia=1
root.Layout.Axis=yes
root.Layout.OwnHomePageEnabled=no
root.Layout.OwnHomePagePath=dummy
root.Layout.MPEGInstallationEnabled=yes
root.Layout.H264InstallationEnabled=yes
root.Layout.AACInstallationEnabled=yes
root.Layout.EnableBasicSetup=yes
root.Layout.InstantReplayEnabled=no
root.Layout.InstantReplayTimeOffset=30
root.Layout.PlayAudioClipEnabled=yes
root.Layout.CustomLink.C0.Enabled=no
root.Layout.CustomLink.C0.Name=Custom link 1
root.Layout.CustomLink.C0.URL=http://
root.Layout.CustomLink.C0.Usage=cgi
root.Layout.CustomLink.C1.Enabled=no
root.Layout.CustomLink.C1.Name=Custom link 2
root.Layout.CustomLink.C1.URL=http://
root.Layout.CustomLink.C1.Usage=cgi
root.Layout.CustomLink.C2.Enabled=no
root.Layout.CustomLink.C2.Name=Custom link 3
root.Layout.CustomLink.C2.URL=http://
root.Layout.CustomLink.C2.Usage=cgi
root.Layout.CustomLink.C3.Enabled=no
root.Layout.CustomLink.C3.Name=Custom link 4
root.Layout.CustomLink.C3.URL=http://
root.Layout.CustomLink.C3.Usage=cgi
root.Layout.Trigger.T0.Enabled=no
root.LightControl.L0.Name=Light
root.LightControl.L0.DriverType=pwm
root.LightControl.L0.SourceType=whiteled
root.LightControl.L0.Driver=pa18
root.LightControl.L0.Button=actinact
root.LightControl.L0.Activate=-100
root.LightControl.L0.Inactivate=-0
root.LightControl.L0.PulseTime=0
root.Log.Access.MaxSize=40000
root.Log.Access.Critical=detailed
root.Log.Access.Warning=detailed
root.Log.Access.Informational=off
root.Log.System.MaxSize=40000
root.Log.System.Critical=on
root.Log.System.Warning=on
root.Log.System.Informational=on
root.MailLogd.ToEmail=
root.MailLogd.LogSendLevel=0
root.MediaClip.MaxGroups=10
root.MediaClip.M0.Name=Burglar_Alarm_Short
root.MediaClip.M0.Location=/etc/audioclips/Burglar_Alarm_Short_8bit_32kHz_mono_PCM-16bit-little.wav
root.MediaClip.M0.Type=audio
root.MediaClip.M6.Name=Camera clicks
root.MediaClip.M6.Location=/etc/audioclips/camera_clicks16k.au
root.MediaClip.M6.Type=audio
root.MediaClip.M7.Name=Pssst, Psst!
root.MediaClip.M7.Location=/etc/audioclips/pssst_psst16k.au
root.MediaClip.M7.Type=audio
root.MediaClip.M8.Name=Intruder
root.MediaClip.M8.Location=/etc/audioclips/intruder16k.au
root.MediaClip.M8.Type=audio
root.MediaClip.M9.Name=Dog barking
root.MediaClip.M9.Location=/etc/audioclips/dog_barking16k.au
root.MediaClip.M9.Type=audio
root.Motion.M0.Name=DefaultWindow
root.Motion.M0.ImageSource=0
root.Motion.M0.Left=0
root.Motion.M0.Right=9999
root.Motion.M0.Top=86
root.Motion.M0.Bottom=9998
root.Motion.M0.WindowType=include
root.Motion.M0.Sensitivity=95
root.Motion.M0.History=93
root.Motion.M0.ObjectSize=3
root.Network.Media=auto
root.Network.Autoneg=normal
root.Network.InterfaceSelectMode=auto
root.Network.HostName=axis-00408c9a1f56
root.Network.DNSServer1=192.168.69.251
root.Network.DNSServer2=0.0.0.0
root.Network.tcpECN=1
root.Network.Enabled=yes
root.Network.BootProto=none
root.Network.IPAddress=192.168.68.127
root.Network.SubnetMask=255.255.254.0
root.Network.Broadcast=192.168.69.255
root.Network.DefaultRouter=192.168.69.254
root.Network.DomainName=
root.Network.ARPPingIPAddress.Enabled=yes
root.Network.AxisNS.Enabled=yes
root.Network.AxisNS.LockButton=no
root.Network.AxisNS.UpdatePeriod=1
root.Network.AxisNS.CheckPeriod=10
root.Network.AxisNS.ServerList=www0.axiscam.net,www1.axiscam.net,195.60.68.29,195.60.68.30
root.Network.AxisNS.ServerPath=reg_cam.php
root.Network.AxisNS.ServerLink=www.axiscam.net
root.Network.AxisNS.CheckIPAddress=0.0.0.0
root.Network.AxisNS.CheckTTL=0
root.Network.Bonjour.Enabled=yes
root.Network.Bonjour.FriendlyName=AXIS M1031-W - 00408C9A1F56
root.Network.DHCP.StoreIPAddresseth0=no
root.Network.DHCP.StoreIPAddresseth1=no
root.Network.DHCP.IPCheckEnabled=yes
root.Network.DHCP.VendorClass=AXIS,Network Camera,M1031-W,5.20.1
root.Network.DHCP.Fqdn=
root.Network.DHCP.Timeout=0
root.Network.DHCP.Retries=20
root.Network.DNSUpdate.Enabled=no
root.Network.DNSUpdate.DNSName=Securitec
root.Network.DNSUpdate.TTL=30
root.Network.eth0.MACAddress=00:40:8C:9A:1F:56
root.Network.eth0.IPAddress=192.168.68.127
root.Network.eth0.SubnetMask=255.255.254.0
root.Network.eth0.Broadcast=192.168.69.255
root.Network.eth0.IPv6.IPAddresses=fe80::240:8cff:fe9a:1f56/64
root.Network.Filter.Enabled=no
root.Network.Filter.Input.Policy=allow
root.Network.Filter.Input.AcceptAddresses=
root.Network.Filter.Log.Enabled=yes
root.Network.FTP.Enabled=yes
root.Network.HTTP.AuthenticationPolicy=basic_digest
root.Network.HTTP.AuthenticationPolicySet=yes
root.Network.HTTP.AuthenticationWithQop=no
root.Network.Interface.I0.SystemDevice=eth0
root.Network.Interface.I0.Type=802.3
root.Network.Interface.I0.Active.MACAddress=00:40:8C:9A:1F:56
root.Network.Interface.I0.Active.Active=no
root.Network.Interface.I0.Active.IPAddress=
root.Network.Interface.I0.Active.SubnetMask=
root.Network.Interface.I0.Active.Broadcast=
root.Network.Interface.I0.Active.IPv6Addresses=
root.Network.Interface.I0.dot1x.Enabled=no
root.Network.Interface.I0.dot1x.EAPOLVersion=1
root.Network.Interface.I0.dot1x.Status=Stopped
root.Network.Interface.I0.dot1x.EAPTLS.Identity=xxx
root.Network.Interface.I0.dot1x.EAPTLS.PrivateKeyPassword=*****
root.Network.Interface.I0.Link.MTU=1500
root.Network.Interface.I0.Link.BootProto=none
root.Network.Interface.I0.Link.Media=auto
root.Network.Interface.I0.Link.Autoneg=normal
root.Network.Interface.I0.Link.IPv4Enabled=yes
root.Network.Interface.I0.Link.IPv6Enabled=no
root.Network.Interface.I0.Link.AcceptRA=yes
root.Network.Interface.I0.Link.DHCPv6=auto
root.Network.Interface.I0.Manual.IPAddress=192.168.68.127
root.Network.Interface.I0.Manual.SubnetMask=255.255.254.0
root.Network.Interface.I0.Manual.Broadcast=192.168.69.255
root.Network.Interface.I0.Manual.DefaultRouter=192.168.69.254
root.Network.Interface.I0.Manual.IPv6Address=
root.Network.Interface.I0.Manual.IPv6DefaultRouter=
root.Network.Interface.I0.ZeroConf.Enabled=yes
root.Network.Interface.I0.ZeroConf.IPAddress=
root.Network.Interface.I0.ZeroConf.SubnetMask=
root.Network.Interface.I1.SystemDevice=eth1
root.Network.Interface.I1.Type=802.11
root.Network.Interface.I1.Active.MACAddress=00:40:8C:9A:1F:56
root.Network.Interface.I1.Active.Active=yes
root.Network.Interface.I1.Active.IPAddress=192.168.68.127
root.Network.Interface.I1.Active.SubnetMask=255.255.254.0
root.Network.Interface.I1.Active.Broadcast=192.168.69.255
root.Network.Interface.I1.Active.IPv6Addresses=fe80::240:8cff:fe9a:1f56/64
root.Network.Interface.I1.dot1x.EAPOLVersion=1
root.Network.Interface.I1.dot1x.EAPTLS.Identity=
root.Network.Interface.I1.dot1x.EAPTLS.PrivateKeyPassword=*****
root.Network.Interface.I1.Link.MTU=1500
root.Network.Interface.I1.Link.BootProto=none
root.Network.Interface.I1.Link.IPv4Enabled=yes
root.Network.Interface.I1.Link.IPv6Enabled=no
root.Network.Interface.I1.Link.AcceptRA=yes
root.Network.Interface.I1.Link.DHCPv6=auto
root.Network.Interface.I1.Manual.IPAddress=192.168.68.127
root.Network.Interface.I1.Manual.SubnetMask=255.255.254.0
root.Network.Interface.I1.Manual.Broadcast=192.168.69.255
root.Network.Interface.I1.Manual.DefaultRouter=192.168.69.254
root.Network.Interface.I1.Manual.IPv6Address=
root.Network.Interface.I1.Manual.IPv6DefaultRouter=
root.Network.Interface.I1.ZeroConf.Enabled=yes
root.Network.Interface.I1.ZeroConf.IPAddress=169.254.248.199
root.Network.Interface.I1.ZeroConf.SubnetMask=255.255.0.0
root.Network.IPv6.Enabled=no
root.Network.IPv6.AcceptRA=yes
root.Network.IPv6.DHCPv6=auto
root.Network.IPv6.IPAddress=
root.Network.IPv6.DefaultRouter=
root.Network.QoS.Class1.Desc=AxisLiveVideo
root.Network.QoS.Class1.DSCP=0
root.Network.QoS.Class2.Desc=AxisLiveAudio
root.Network.QoS.Class2.DSCP=0
root.Network.QoS.Class3.Desc=AxisEventAlarm
root.Network.QoS.Class3.DSCP=0
root.Network.QoS.Class4.Desc=AxisManagement
root.Network.QoS.Class4.DSCP=0
root.Network.Resolver.NameServerList=192.168.69.251 
root.Network.Resolver.ObtainFromDHCP=no
root.Network.Resolver.Search=
root.Network.Resolver.NameServer1=192.168.69.251
root.Network.Resolver.NameServer2=
root.Network.Routing.DefaultRouter=192.168.69.254
root.Network.Routing.IPv6.DefaultRouter=
root.Network.RTP.NbrOfRTPGroups=1
root.Network.RTP.StartPort=50000
root.Network.RTP.EndPort=50999
root.Network.RTP.VideoDSCP=0
root.Network.RTP.AudioDSCP=0
root.Network.RTP.R0.VideoAddress=239.226.31.86
root.Network.RTP.R0.VideoPort=0
root.Network.RTP.R0.AudioAddress=239.226.31.214
root.Network.RTP.R0.AudioPort=0
root.Network.RTP.R0.TTL=5
root.Network.RTSP.Enabled=yes
root.Network.RTSP.Port=554
root.Network.RTSP.Timeout=60
root.Network.RTSP.ProtViewer=password
root.Network.RTSP.AllowPathAsURL=yes
root.Network.RTSP.AuthenticateOverHTTP=no
root.Network.RTSP.AllowClientTransportSettings=no
root.Network.UPnP.Enabled=yes
root.Network.UPnP.FriendlyName=AXIS M1031-W - Office WiFi Cam
root.Network.UPnP.NATTraversal.Enabled=no
root.Network.UPnP.NATTraversal.Router=
root.Network.UPnP.NATTraversal.ExternalIPAddress=
root.Network.UPnP.NATTraversal.Active=no
root.Network.UPnP.NATTraversal.MinPort=32768
root.Network.UPnP.NATTraversal.MaxPort=65535
root.Network.VolatileHostName.ObtainFromDHCP=no
root.Network.VolatileHostName.HostName=axis-00408c9a1f56
root.Network.Wireless.ESSID=SecuriTec
root.Network.Wireless.MODE=managed
root.Network.Wireless.W0.Enabled=yes
root.Network.Wireless.W0.Method=WPA-PSK
root.Network.Wireless.W0.GenerationMethod=psk-phrase
root.Network.Wireless.W0.Passphrase=*****
root.Network.Wireless.W0.Key=
root.Network.Wireless.W1.Enabled=no
root.Network.Wireless.W1.Method=WPA-ENTERPRISE
root.Network.Wireless.W1.Dot1XMethod=EAPTLS
root.Network.Wireless.WEP.Enabled=no
root.Network.Wireless.WEP.KeyLength=128
root.Network.Wireless.WEP.GenerationMethod=manual
root.Network.Wireless.WEP.Passphrase=
root.Network.Wireless.WEP.ActiveKey=1
root.Network.Wireless.WEP.Key1=
root.Network.Wireless.WEP.Key2=
root.Network.Wireless.WEP.Key3=
root.Network.Wireless.WEP.Key4=
root.Network.Wireless.WEP.Authentication=open
root.Network.ZeroConf.Enabled=yes
root.Network.ZeroConf.IPAddress=169.254.248.199
root.Network.ZeroConf.SubnetMask=255.255.0.0
root.Notify.AtBoot=no
root.Notify.TextType=simple
root.Notify.TextField=Your text here
root.Notify.KnownIP=192.168.68.127
root.Notify.KnownIPV6=
root.Notify.FTP.Enabled=no
root.Notify.FTP.HostName=
root.Notify.FTP.UserName=
root.Notify.FTP.Password=
root.Notify.FTP.UploadPath=
root.Notify.FTP.PassiveMode=no
root.Notify.FTP.Port=21
root.Notify.HTTP.Enabled=no
root.Notify.HTTP.URL=http://
root.Notify.HTTP.Custom=
root.Notify.HTTP.UserName=
root.Notify.HTTP.Password=
root.Notify.HTTP.Proxy=
root.Notify.HTTP.ProxyPort=
root.Notify.HTTP.ProxyUser=
root.Notify.HTTP.ProxyPass=
root.Notify.SMTP.Enabled=no
root.Notify.SMTP.ToEmail=
root.Notify.SMTP.FromEmail=
root.Notify.SMTP.Subject=
root.Output.NbrOfOutputs=0
root.PIRSensor.Sensitivity=75
root.Properties.API.HTTP.Version=3
root.Properties.API.HTTP.AdminPath=/operator/basic.shtml
root.Properties.API.Metadata.Metadata=yes
root.Properties.API.Metadata.Version=1.0
root.Properties.API.RTSP.Version=2.01
root.Properties.API.RTSP.RTSPAuth=yes
root.Properties.API.WebService.WebService=yes
root.Properties.API.WebService.ONVIF.ONVIF=yes
root.Properties.API.WebService.ONVIF.Version=1.01
root.Properties.Audio.Audio=yes
root.Properties.Audio.Format=g711,g726,aac
root.Properties.Audio.DuplexMode=full,half,post,get
root.Properties.Audio.InputType=mic
root.Properties.Audio.Decoder.Format=g711,g726,axis-mulaw-128
root.Properties.Firmware.BuildNumber=1
root.Properties.Firmware.BuildDate=Jun 23 2016 13:16
root.Properties.Firmware.Version=5.20.4
root.Properties.HTTPS.HTTPS=yes
root.Properties.Image.Rotation=0,180
root.Properties.Image.Resolution=640x480,480x360,320x240,240x180,160x120,176x144
root.Properties.Image.Format=jpeg,mjpeg,mpeg4,h264,bitmap
root.Properties.Image.NbrOfViews=1
root.Properties.LightControl.LightControl=yes
root.Properties.Motion.Motion=yes
root.Properties.Motion.MaxNbrOfWindows=10
root.Properties.RemoteService.RemoteService=yes
root.Properties.RTC.RTC=no
root.Properties.System.Language=English
root.Properties.System.HardwareID=170
root.Properties.System.SerialNumber=00408C9A1F56
root.Properties.System.Architecture=armv5tejl
root.Properties.Tampering.Tampering=yes
root.Properties.TemperatureSensor.TemperatureSensor=yes
root.Properties.TemperatureSensor.TemperatureControl=no
root.Properties.TemperatureSensor.Fan=no
root.Properties.TemperatureSensor.Heater=no
root.RemoteService.Enabled=oneclick
root.RemoteService.Proxy=
root.RemoteService.RemoteServerURL=http://dispatcher.sts.axis.com:80/axissts/axissts.cgi,http://dispatcher.sts.axis.com:8080/axissts/axissts.cgi,http://dispatchse1.sts.axis.com:80/axissts/axissts.cgi,http://dispatchse1.sts.axis.com:8080/axissts/axissts.cgi,http://dispatchse2.sts.axis.com:80/axissts/axissts.cgi,http://dispatchse2.sts.axis.com:8080/axissts/axissts.cgi,http://dispatchus1.sts.axis.com:80/axissts/axissts.cgi,http://dispatchjp1.sts.axis.com:80/axissts/axissts.cgi,http://87.237.210.63:80/axissts/axissts.cgi,http://87.237.210.63:8080/axissts/axissts.cgi,http://85.235.16.249:80/axissts/axissts.cgi,http://85.235.16.249:8080/axissts/axissts.cgi,http://85.235.16.250:80/axissts/axissts.cgi,http://85.235.16.250:8080/axissts/axissts.cgi
root.RemoteService.Timeout=100
root.RemoteService.ConnectTimeout=15
root.RemoteService.BrandSpec=1275677567
root.RemoteService.Reconnect=0
root.RemoteService.TimeMode=NTP
root.SMTP.MailServer1=
root.SMTP.MailServer2=
root.SMTP.MailServerPort1=25
root.SMTP.MailServerPort2=25
root.SMTP.MailServerSSL1=no
root.SMTP.MailServerSSL2=no
root.SMTP.FromEmail=
root.SMTP.Authentication.A1.Enabled=no
root.SMTP.Authentication.A1.UserName=
root.SMTP.Authentication.A1.Password=
root.SMTP.Authentication.A1.WeakestMethod=Login
root.SMTP.Authentication.A1.UsePOP=no
root.SMTP.Authentication.A1.POPServer=
root.SMTP.Authentication.A2.Enabled=no
root.SMTP.Authentication.A2.UserName=
root.SMTP.Authentication.A2.Password=
root.SMTP.Authentication.A2.WeakestMethod=Login
root.SMTP.Authentication.A2.UsePOP=no
root.SMTP.Authentication.A2.POPServer=
root.SMTP.SSL.S1.RootCertificate=
root.SMTP.SSL.S1.ClientCertificate=
root.SMTP.SSL.S1.ClientPrivateKey=
root.SMTP.SSL.S1.ClientPrivateKeyPasswd=
root.SMTP.SSL.S2.RootCertificate=
root.SMTP.SSL.S2.ClientCertificate=
root.SMTP.SSL.S2.ClientPrivateKey=
root.SMTP.SSL.S2.ClientPrivateKeyPasswd=
root.SNMP.Enabled=no
root.SNMP.InitialUserPasswdSet=no
root.SNMP.InitialUserPasswd=*****
root.SNMP.EngineBoots=1
root.SNMP.V1=no
root.SNMP.V2c=no
root.SNMP.V3=no
root.SNMP.V1ReadCommunity=public
root.SNMP.V1WriteCommunity=write
root.SNMP.DSCP=0
root.SNMP.Trap.Enabled=no
root.SNMP.Trap.T0.Address=
root.SNMP.Trap.T0.Community=public
root.SNMP.Trap.T0.AuthFail.Enabled=no
root.SNMP.Trap.T0.ColdStart.Enabled=no
root.SNMP.Trap.T0.LinkUp.Enabled=no
root.SNMP.Trap.T0.WarmStart.Enabled=no
root.SOCKS.Enabled=no
root.SOCKS.Server=socks
root.SOCKS.ServerPort=1080
root.SOCKS.ServerType=4
root.SOCKS.LocalNetworks=10.0.0.0/255.0.0.0, 172.16.0.0/255.240.0.0, 192.168.0.0/255.255.255.0
root.SOCKS.UserName=
root.SOCKS.Password=
root.StatusLED.Usage=on
root.StatusLED.FlashInterval=4
root.StreamCache.Size=12582912
root.StreamCache.MaxGroups=20
root.StreamCache.S0.Enabled=no
root.StreamCache.S0.Options=
root.StreamCache.S0.RequestedLengthTime=30
root.StreamProfile.MaxGroups=20
root.StreamProfile.S0.Name=Quality
root.StreamProfile.S0.Description=Best image quality and full frame rate.
root.StreamProfile.S0.Parameters=videocodec=h264&resolution=640x480&compression=20&fps=0&videokeyframeinterval=8&videobitrate=0
root.StreamProfile.S0.Default.Name=Quality
root.StreamProfile.S0.Default.Description=Best image quality and full frame rate.
root.StreamProfile.S0.Default.Parameters=videocodec=h264&resolution=640x480&compression=20&fps=0&videokeyframeinterval=8&videobitrate=0
root.StreamProfile.S1.Name=Balanced
root.StreamProfile.S1.Description=Medium image quality and frame rate.
root.StreamProfile.S1.Parameters=videocodec=h264&resolution=640x480&compression=30&fps=15&videokeyframeinterval=15&videobitrate=0
root.StreamProfile.S1.Default.Name=Balanced
root.StreamProfile.S1.Default.Description=Medium image quality and frame rate.
root.StreamProfile.S1.Default.Parameters=videocodec=h264&resolution=640x480&compression=30&fps=15&videokeyframeinterval=15&videobitrate=0
root.StreamProfile.S2.Name=Bandwidth
root.StreamProfile.S2.Description=Low bandwidth with medium image quality.
root.StreamProfile.S2.Parameters=resolution=320x240&compression=50&fps=15&videokeyframeinterval=32&videobitrate=250&videobitratepriority=framerate&videocodec=h264
root.StreamProfile.S2.Default.Name=Bandwidth
root.StreamProfile.S2.Default.Description=Low bandwidth with medium image quality.
root.StreamProfile.S2.Default.Parameters=videocodec=h264&resolution=640x480&compression=50&fps=15&videokeyframeinterval=32&videobitrate=250&videomaxbitrate=1000&videobitratepriority=framerate
root.StreamProfile.S3.Name=Mobile
root.StreamProfile.S3.Description=Mobile device settings.
root.StreamProfile.S3.Parameters=videocodec=h264&resolution=176x144&compression=50&fps=15&videokeyframeinterval=32&videobitrate=120&videomaxbitrate=128&videobitratepriority=quality&audio=0
root.StreamProfile.S3.Default.Name=Mobile
root.StreamProfile.S3.Default.Description=Mobile device settings.
root.StreamProfile.S3.Default.Parameters=videocodec=h264&resolution=176x144&compression=50&fps=15&videokeyframeinterval=32&videobitrate=120&videomaxbitrate=128&videobitratepriority=quality&audio=0
root.System.BoaPort=80
root.System.AlternateBoaPort=0
root.System.BoaDSCP=0
root.System.BoaProtViewer=password
root.System.RootPwdSet=yes
root.System.BoaGroupPolicy.admin=http
root.System.BoaGroupPolicy.operator=http
root.System.BoaGroupPolicy.viewer=http
root.Tampering.T0.DarkDetectionEnabled=yes
root.Tampering.T0.MinDuration=20
root.Tampering.T0.DarkThreshold=90
root.Time.ServerTime=10:38:13
root.Time.ServerDate=2016-10-26
root.Time.ObtainFromDHCP=no
root.Time.POSIXTimeZone=CET-1CEST,M3.5.0,M10.5.0/3
root.Time.SyncSource=NTP
root.Time.DST.Enabled=yes
root.Time.NTP.VolatileServer=
root.Time.NTP.Server=192.168.69.251
root.WebService.Enabled=no
root.WebService.UsernameToken.ReplayAttackProtection=yes
root.WebService.UsernameToken.WaitForNTP=no

How yould you do this in C#?

Dobi
  • 125
  • 5
  • 15
  • Possible duplicate of [C# mimic associative array of unknown key-number (like in PHP) or different solution](http://stackoverflow.com/questions/40262773/c-sharp-mimic-associative-array-of-unknown-key-number-like-in-php-or-different) – Gilad Green Oct 26 '16 at 14:28
  • Not really, here I ask if someone could give me a completely different way for integrating this. Because the other way I would like seams not to be possible. – Dobi Oct 26 '16 at 14:32
  • Might be possible with dictionaries but the implementation will be weird and not very dynamic(if you want to add an extra layer). And honestly root["RemoteService"]["BrandSpec"]=1275677567 doesn't seem to be better than root.RemoteService.BrandSpec=1275677567 – Lidaranis Oct 26 '16 at 14:32
  • 2
    Well, the way in which you have listed all your settings seems to be a perfect example of classes with nested classes. – Steve Oct 26 '16 at 14:34
  • And those can be generated dynamically (classes with nested classes)? Because the list of settings is a string which I get from a network device. (Depending of the device it will be different but the layout stays the same.) – Dobi Oct 26 '16 at 14:38
  • Can you tell us what you are trying to do? The only generic way I can see to handle this is where every single "setting" is a string, meaning when you are done, both of these assignments would be legal even though only one makes sense: `root.Image.I0.Appearance.Resolution=640x480`, `root.Image.I0.Appearance.Resolution="Some string that is not a resolution"`. Why do you need all of these "settings" inside of c#, are you both getting and setting them somehow? – Quantic Oct 26 '16 at 14:40
  • The settings I get is a long string from a network camera. Different cameras will give me different settings, but the layout (ex. root.Image.I0.Appearance.Resolution=640x480) is always the same. Now I want to list them in C# somehow, so that I can access them easily. – Dobi Oct 26 '16 at 14:43
  • And what do you do with the settings? Is this a backup of sorts where down the line you want to be able to restore them? In which case how does your network camera accept settings changes? Why can't you just save the settings you showed us into "NetworkCameraSettings.txt", why do they have to go into c# structures? – Quantic Oct 26 '16 at 14:45
  • Those cameras have a web-interface where you can change most of those settings, but not all of them. Now I want to write a own interface where I can change the variables I need. Also I want to integrate some default settings for multiple types of cameras. The list of settings you see is a list I get from the camera api. To change the settings I can do it like: http:///axis-cgi/param.cgi?action=update&AudioSource.A0.OutputGain=20 – Dobi Oct 26 '16 at 14:50
  • 1
    It looks like these `ExpandoObject` answers are close to what you need in that case, but you will have to reconstruct the string which may actually be quite complicated on this `ExpandoObject`. I.e., @heinzbenz shows `Console.WriteLine(">> " + root.System.BoaPort)` which will print (for a setting of 50): `>> 50`, but you need the *string* `"System.BoaPort=50"` to feed into the URL. Retrieving the string that represents the member named "System" and the member named "BoaPort" can usually be accessed through reflection, but maybe there's weirdness with this `dynamic` ExpandoObject. – Quantic Oct 26 '16 at 14:58

3 Answers3

2

You can use an ExpandoObject with a params indexer to access it, something like this (that's just an example, you'll need to do some testing around it and handle things like single key access etc):

public class AssociativeArray
{
    private dynamic _data = new ExpandoObject();

    public object this[params string[] keys]
    {
        get
        {
            dynamic lastObject = _data;
            foreach (var key in keys.Take(keys.Count() - 1))
            {
                var dic = lastObject as IDictionary<string, Object>;
                lastObject = dic[key] as ExpandoObject;
            }
            return (lastObject as IDictionary<string, object>)[keys.Last()];
        }
        set
        {
            dynamic lastObject = _data;
            foreach (var key in keys.Take(keys.Count() - 1))
            {
                var dic = lastObject as IDictionary<string, Object>;
                dic.Add(key, new ExpandoObject());
                lastObject = dic[key];
            }
            (lastObject as IDictionary<string, object>).Add(keys.Last(), value);
        }
    }
}

you can then use it like this:

var arr = new AssociativeArray();
arr["root", "Audio", "Dup"] = 33;
Console.Write(arr["root", "Audio", "Dup"]);

PS. I'm using the suggestion from this answer to cast the ExpandoObject as a Dictionary

Community
  • 1
  • 1
KMoussa
  • 1,568
  • 7
  • 11
1

You can use a ExpandoObject for this case. You can cast the ExpandoObject to a Dictionary and add the values:

var text = File.ReadAllText("$settingsfile");
var keyValuePairs = text.Split('\n')
    .Select(line => Tuple.Create(line.Split('=')[0].Trim(), line.Split('=')[1].Trim()));

dynamic root = new ExpandoObject();

foreach (var tup in keyValuePairs)
{
    var path = tup.Item1.Split('.').Skip(1).ToList();
    var setting = path.Last();
    var value = tup.Item2;

    IDictionary<string, object> resolvedObject = root;

    foreach (var component in path.Take(path.Count - 1))
    {
        if (!resolvedObject.ContainsKey(component))
        {
            resolvedObject.Add(component, new ExpandoObject());
        }

        resolvedObject = (IDictionary<string, object>) resolvedObject[component];
    }

    resolvedObject[setting] = value;
}

Console.WriteLine(">> " + root.System.BoaPort);
Nico
  • 3,542
  • 24
  • 29
0

Thanks to KMoussa!

Not the most beautiful code, but it works:

public class cAssociativeArray
{
    private dynamic _data = new ExpandoObject();

    public object this[params string[] keys]
    {
        get { return getValue(keys); }
        set { setValue(value, keys); }
    }


    private void setValue(object _value, params string[] keys)
    {
        dynamic lastObject = _data;
        string lKey = keys.Last();

        foreach (var key in keys.Take(keys.Count() - 1))
        {
            var dic = lastObject as IDictionary<string, Object>;
            if (!dic.ContainsKey(key))
            {
                dic.Add(key, new ExpandoObject());
            }
            lastObject = dic[key];
        }

        if ((lastObject as IDictionary<string, object>) != null)
        {
            if (!(lastObject as IDictionary<string, object>).ContainsKey(keys.Last())) // add value
            {
                (lastObject as IDictionary<string, object>).Add(lKey, _value);
            }
            else //change value
            {
                if (keys.Count() > 1)
                {
                    (lastObject as IDictionary<string, object>)[lKey] = _value;
                }
            }
        }
    }


    private string getValue(params string[] keys)
    {
        dynamic lastObject = _data;
        string lKey = keys.Last();

        foreach (var key in keys.Take(keys.Count() - 1))
        {
            var dic = lastObject as IDictionary<string, Object>;
            if ((dic != null) && (dic.ContainsKey(key)))
            {
                lastObject = dic[key] as ExpandoObject;
            }
            else
            {
                return null;
            }
        }

        if (((lastObject as IDictionary<string, object>) != null) && ((lastObject as IDictionary<string, object>).ContainsKey(lKey))
                                                                  && (!((lastObject as IDictionary<string, object>)[lKey] is ExpandoObject)))
        {
            return (lastObject as IDictionary<string, object>)[lKey].ToString();
        }
        else
        {
            return null;
        }
    }


    public string[] getKeys(params string[] keys)
    {
        dynamic lastObject = _data;

        foreach (var key in keys.Take(keys.Count()))
        {
            var dic = lastObject as IDictionary<string, Object>;
            if ((dic != null) && (dic.ContainsKey(key)))
            {
                lastObject = dic[key] as ExpandoObject;
            }
            else
            {
                return null;
            }
        }

        if ((lastObject as IDictionary<string, object>) != null)
        {
            return (lastObject as IDictionary<string, object>).Keys.ToArray();
        }
        else
        {
            return null;
        }
    }


    public int countKeys(params string[] keys)
    {
        dynamic lastObject = _data;

        foreach (var key in keys.Take(keys.Count()))
        {
            var dic = lastObject as IDictionary<string, Object>;
            if ((dic != null) && (dic.ContainsKey(key)))
            {
                lastObject = dic[key] as ExpandoObject;
            }
            else
            {
                return -1;
            }
        }

        if ((lastObject as IDictionary<string, object>) != null)
        {
            return (lastObject as IDictionary<string, object>).Count();
        }
        else
        {
            return -1;
        }
    }


    public void printDebug(params string[] keys)
    {
        Debug.WriteLine("");
        printDebugSub("", keys);
        Debug.WriteLine("");
    }

    private void printDebugSub(string spaceStr, params string[] keys)
    {
        dynamic lastObject = _data;

        foreach (var key in keys.Take(keys.Count()))
        {
            var dic = lastObject as IDictionary<string, Object>;
            if ((dic != null) && (dic.ContainsKey(key)))
            {
                lastObject = dic[key] as ExpandoObject;
            }
        }

        if ((lastObject as IDictionary<string, object>) != null)
        {
            foreach (string keyStr in (lastObject as IDictionary<string, object>).Keys.ToArray())
            {
                string valueStr = "";
                if (!((lastObject as IDictionary<string, object>)[keyStr] is ExpandoObject))
                {
                    valueStr = " = " + (lastObject as IDictionary<string, object>)[keyStr].ToString();
                }

                Debug.WriteLine(spaceStr + keyStr + valueStr);

                List<string> lst = keys.ToList();
                lst.Add(keyStr);
                printDebugSub(spaceStr.Trim() + "---- ", lst.ToArray());
            }
        }
        else
        {
            return;
        }
    }
}
Dobi
  • 125
  • 5
  • 15