dani
Goto Top

Wie kann ich auf Werte eines JSON-Arrays zugreifen?

Guten Morgen Kolleginnen und Kollegen,
erstmal auch noch von meiner Seite eine gutes neues Jahr.

Ich versuche zur Zeit, über die RIPE Database RESTful API zu einem bestimmten AS, sämtliche IP-Subnetze auszulesen. Am Schluss sollen die Werte in eine CSV-Datei geschrieben werden, welche als Namen z.b. as3320.csv besitzt. Das ist erstmal zweitrangig...

So rufe ich die Daten ab:
$rest = Invoke-RestMethod -Uri "http://rest.db.ripe.net/search.json?query-string=AS3320&inverse-attribute=origin&type-filter=route" -ContentType application/json -Method Get  

Wenn ich danach in der Powershell foglendes "$rest.objects.object.attributes" eingebe, erhalte ich folgende Ausgabe:
attribute                                                                                                                                                                                                                                                        
---------                                                                                                                                                                                                                                                        
{@{name=route; value=103.244.56.0/23}, @{name=descr; value=part of 103.244.56.0/22}, @{name=descr; value=LENOVO (shanghai) Co.ltd}, @{name=descr; value=registered at APNIC}...}                                                                                 
{@{name=organisation; value=ORG-LCL10-RIPE}, @{name=org-name; value=Lenovo (Shanghai) Co., Ltd.}, @{name=org-type; value=OTHER}, @{name=address; value=Shanghai, China}...}                                                                                      
{@{name=route; value=109.237.176.0/20}, @{name=descr; value=T-Mobile Deutschland GmbH}, @{name=remarks; value=secure routing by AS3320 aggregate}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}...}                                              
{@{name=route; value=129.181.208.0/21}, @{name=descr; value=TENOVIS}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                                             
{@{name=route; value=129.181.216.0/22}, @{name=descr; value=BULL}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                                                
{@{name=route; value=131.176.233.0/24}, @{name=descr; value=European Space Agency (ESA)}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                         
{@{name=route; value=131.176.234.0/24}, @{name=descr; value=European Space Agency (ESA)}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                         
{@{name=route; value=131.176.235.0/24}, @{name=descr; value=European Space Agency (ESA)}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                         
{@{name=route; value=131.176.236.0/24}, @{name=descr; value=European Space Agency (ESA)}, @{link=; name=origin; value=AS3320; referenced-type=aut-num}, @{link=; name=mnt-by; value=DTAG-RR; referenced-type=mntner}...}                                         
...
Ich habe das Ergebnis etwas gekürzt, da das Schema immer das Gleiche ist.
Wie ich auf die ersten Wert von name=route zugreife weiß ich noch. face-smile Aber wie komme ich an die Werte von name=descr und name=origin?


Gruß,
Dani

Content-Key: 292039

Url: https://administrator.de/contentid/292039

Printed on: April 19, 2024 at 23:04 o'clock

Mitglied: 114757
114757 Jan 01, 2016 at 10:56:12 (UTC)
Goto Top
$rest.objects.object.attributes | ?{$_.Name -eq 'descr'}  

usw.

Gruß jodel32
Member: Dani
Dani Jan 01, 2016 updated at 11:00:58 (UTC)
Goto Top
Moin @114757,
seltsam, genau die Abfrage funktioniert bei mir nicht. Wie hast du es bei dir getestet?
Ich habe ne Powershell geöffnet, schreibe die Rückgabe in die Variable $rest und führe deine Abfrage aus.


Gruß,
Dani
Mitglied: 114757
114757 Jan 01, 2016 at 11:02:12 (UTC)
Goto Top
Bin noch unterwegs teste nachher....
Mitglied: 114757
Solution 114757 Jan 01, 2016, updated at Jan 02, 2016 at 16:04:18 (UTC)
Goto Top
$query = 'AS3320'  
$rest = Invoke-RestMethod -Uri "http://rest.db.ripe.net/search.json?query-string=$query&inverse-attribute=origin&type-filter=route" -ContentType application/json -Method Get  
$rest.objects.object.attributes | select @{n='Description';e={($_.attribute | ?{$_.name -eq 'descr'} | select -Expand Value) -join ','}},@{n='route';e={$_.attribute | ?{$_.name -eq 'route'} | select -Expand Value}},@{n='Origin';e={$_.attribute | ?{$_.name -eq 'origin'} | select -Expand Value}} | export-csv "C:\$query.csv" -Delimiter ";" -NoType -Encoding UTF8  
Member: colinardo
Solution colinardo Jan 01, 2016, updated at Jan 02, 2016 at 16:04:17 (UTC)
Goto Top
Hallo Dani, frohes neues face-smile

oder so für alle Felder mit Datumsumwandlung
$query = 'AS3320'  
$rest = Invoke-RestMethod -Uri "http://rest.db.ripe.net/search.json?query-string=$([System.Web.HttpUtility]::UrlEncode($query))&inverse-attribute=origin&type-filter=route" -ContentType application/json -Method Get  
$obj = @()
$rest.objects.object.attributes | %{
    $entry = @{}
    $_.attribute | %{$entry[$_.name] += $_.Value}
    $entry.'last-modified' = get-date $entry.'last-modified' -EA SilentlyContinue  
    $entry.created = get-date $entry.created -EA SilentlyContinue
    $obj += New-Object PSObject -Property $entry
}
$obj | export-csv "C:\$query.csv" -Delimiter ";" -NoType -Encoding UTF8  
Grüße Uwe
Member: Dani
Dani Jan 01, 2016 updated at 15:16:02 (UTC)
Goto Top
Hi Jodel32,
ohh, wow... so einfach kommt an die Werte ran. face-confused Vielen Dan erstmal dafür!
Der Operator -join ist weshalb notwendig?


Gruß,
Dani
Member: Dani
Dani Jan 01, 2016 updated at 15:27:36 (UTC)
Goto Top
Hallo Uwe,
vielen Dank auch an dich. Drei Fragen stellen sich:
1) Warum hast du bei der Abfrage $([System.Web.HttpUtility]::UrlEncode($query)) gesetzt?
2) Verstehe ich das richtig, dass du in deinem Beispiel über zwei foreach - Schleifen zum Ziel kommst? Die Aliase sind mir noch nicht ganz so geläufig...
3)Was genau passiert hier? Klar es wird ein neues Object erstellt aber warum.
$obj += New-Object PSObject -Property $entry


Gruß,
Dani
Member: colinardo
colinardo Jan 01, 2016 updated at 15:27:06 (UTC)
Goto Top
Zitat von @Dani:
Der Operator -join ist weshalb notwendig?
Weil in der Ausgabe mehrere Felder mit dem selben Namen vorhanden sind, die damit zusammengefasst werden.
Die Verteilen damit längere Zeilen auf mehrere Felder mit dem selben Namen. Das descr-Feld ist ein Beispiel.

Grüße Uwe
Member: colinardo
colinardo Jan 01, 2016 updated at 15:35:47 (UTC)
Goto Top
Zitat von @Dani:

Hallo Uwe,
vielen Dank auch an dich. Drei Fragen stellen sich:
1) Warum hast du bei der Abfrage $([System.Web.HttpUtility]::UrlEncode($query)) gesetzt?
Das ist Best-Practice wenn der Eingabestring $query z.B. Sonderzeichen enthält, die werden dan URL-Konform escaped/umgewandelt.

2) Verstehe ich das richtig, dass du in deinem Beispiel über zwei foreach - Schleifen zum Ziel kommst? Die Aliase sind mir noch nicht ganz so geläufig...
Ja %{} ist eine Abkürzung für eine Foreach Schleife
3)Was genau passiert hier? Klar es wird ein neues Object erstellt aber warum.
$obj += New-Object PSObject -Property $entry
Für jeden Eintrag wird eine Hashtable $entry erstellt, dieser Hashtable werden alle Felder des Eintrags hinzugefügt, doppelte werden zusammengefasst bzw. die Strings hinten angehängt.
Dann formatiere ich die beiden Datumswerte.
Und zum Schluss wird aus der Hashtable ein Custom-Object erzeugt das dem Array $obj hinzugefügt wird.
Das ist eine gängige Methode Daten für den CSV-Export aufzubereiten.
Du kannst es zwar auch wie jodel es mit Calculated Properties gezeigt hat machen, dann musst du aber jede Eigenschaft einzeln als Property hinzufügen, das macht das ganze unhandlich und etwas unübersichtlich. Mit meiner Variante erfasst du automatisch jedes Feld.
Member: Dani
Dani Jan 02, 2016 at 14:11:47 (UTC)
Goto Top
Hallo Uwe,
ich kann keinen Unterschied zwischen den Ausgaben mit/ohne -join feststellen.


Gruß,
Dani
Member: Dani
Dani Jan 02, 2016 updated at 14:15:16 (UTC)
Goto Top
Hallo Uwe,
Das ist Best-Practice wenn der Eingabestring $query z.B. Sonderzeichen enthält, die werden dan URL-Konform escaped/umgewandelt.
Unter Windows 10, Powershell 5 wird ein Fehler ausgegeben:
Der Typ [System.Web.HttpUtility] wurde nicht gefunden.

Du kannst es zwar auch wie jodel es mit Calculated Properties gezeigt hat machen, dann musst du aber jede Eigenschaft einzeln als Property hinzufügen, das macht das ganze unhandlich und etwas unübersichtlich. Mit meiner Variante erfasst du automatisch jedes Feld.
Ich benötige eigentlich nur die genannten Felder aus dem JSON-Array. Alle Anderen sind für das Vorhaben egal.


Gruß,
Dani
Mitglied: 114757
114757 Jan 02, 2016 updated at 14:42:16 (UTC)
Goto Top
Zitat von @Dani:

ich kann keinen Unterschied zwischen den Ausgaben mit/ohne -join feststellen.

Den siehst du ja auch nur bei Feldern die mehr als einmal vorhanden sind face-wink Gerade das Description Feld kommt ja oft mehrfach vor!
Geht hier einwandfrei !
Member: colinardo
colinardo Jan 02, 2016 at 14:47:04 (UTC)
Goto Top
Zitat von @Dani:
ich kann keinen Unterschied zwischen den Ausgaben mit/ohne -join feststellen.
Siehe jodel32... Stichwort ist wenn mehrere Felder mit dem selben Namen auftauchen.
Member: colinardo
colinardo Jan 02, 2016 updated at 14:55:21 (UTC)
Goto Top
Zitat von @Dani:
Unter Windows 10, Powershell 5 wird ein Fehler ausgegeben:
Der Typ [System.Web.HttpUtility] wurde nicht gefunden.
Geht hier einwandfrei Windows 7/8/10 etc egal. Ein Importieren eines Namespaces ist hier nicht notwendig, geht out of the box!
Ich nutze das ja in all meinen Skripten, kann also nur bei dir was nicht stimmen.

Dann lasse es halt weg und machs nur mit der Variablen, wenn sie keine Sonderzeichen enthält.

Wen du nicht alle Felder brauchst machst du einfach einen select auf das $obj mit den benötigten Feldern vor dem Export, feddich.
Member: colinardo
Solution colinardo Jan 02, 2016 updated at 16:04:11 (UTC)
Goto Top
p.s.
Unter Windows 10 geht aber alternativ auch
[System.Net.WebUtility]::UrlEncode($query)
geht ebenfalls ohne Import eines Namespaces!

Was'n los Dani face-smile, noch den Schampus vom Jahreswechsel intus ?
Mitglied: 114757
114757 Jan 02, 2016 updated at 15:21:32 (UTC)
Goto Top
Zitat von @colinardo:
p.s.
Unter Windows 10 geht aber alternativ auch
> [System.Net.WebUtility]::UrlEncode($query)
> 
Joa kann ich nur zustimmen, geht hier beides unter Windows 10 ... ohne weitere Voraussetzungen.
Member: Dani
Dani Jan 02, 2016 updated at 16:05:08 (UTC)
Goto Top
Nehme ich die Alternative funktioniert es wie du gesagt hast:
$rest = Invoke-RestMethod -Uri "http://rest.db.ripe.net/search.json?query-string=AS$([System.Net.WebUtility]::UrlEncode($strBgpAs))&inverse-attribute=origin&type-filter=route" -ContentType application/json -Method Get  


Was'n los Dani , noch den Schampus vom Jahreswechsel intus ?
Nee... aber wenn's heut so weiter geht, heute Abend wieder face-smile
Ich habe beide Lösungen ausprobiert und das Result ist immer das Gewünschte. Persönlich gefällt mir die Lösung von @colinardo besser, da ich somit eine Funktion entwerfen kann und je nach Anwendungsfall die notwendigen Informationen aus der Rückgabevariable selektieren kann.

Vielen Dank nochmal an euch beide für die vorzügliche Unterstützung!
Ihr zwei programmiert wohl etwas öfters als ich in meiner Freizeit... face-wink


Gruß,
Danui
Member: colinardo
colinardo Jan 02, 2016 updated at 16:25:34 (UTC)
Goto Top
Zitat von @Dani:
Nehme ich die Alternative funktioniert es wie du gesagt hast:
Na Gott sei Dank face-smile
Bist du in einer Non-Standard PS-Session unterwegs ?
Das aktuellste Windows 10 1511 Enterprise zeigt hier nämlich überall folgendes Verhalten.

0b74927c4c0b154fb147bfcce7cf2082

Schönen Abend
Grüße Uwe