Powershell exporting data from nested JSON - json

I need help with looping through the following JSON file and pull in all the attributes under "snapshot_groupSnapshotChildren""entitySnapshot_properties" For example the "Test", "Guacamole" and the "Heartbeat on Guacamole" are dynamic and the depth can also vary from one subgroup to another subgroup.
JSON File
{
"snapshot_groupSnapshotChildren": {
"Test": {
"entitySnapshot_properties": {
"_dependsCondition": "good",
"_nextID": "2",
"_name": "Test",
"_externalId": "baa97724-9ff8-46ad-b23a-d37d283905d7",
"objcategory": "",
"_id": "1951498570",
"_class": "SubGroup",
"_group": "1951498570",
"_enabled": "true",
"_ownerID": "__SiteScopeRoot__"
},
"snapshot_groupSnapshotChildren": {
"Guacamole": {
"entitySnapshot_properties": {
"_dependsCondition": "good",
"_nextID": "2",
"_name": "Guacamole",
"_externalId": "f08b1069-1943-479d-bb83-7668d833fa58",
"objcategory": "",
"_id": "1951498571",
"_class": "SubGroup",
"_group": "1951498571",
"_enabled": "true",
"_ownerID": "1951498570"
},
"snapshot_groupSnapshotChildren": {},
"entitySnapshot_name": "Guacamole",
"snapshot_alertSnapshotChildren": {},
"entitySnapshot_url": "",
"snapshot_monitorSnapshotChildren": {
"Heartbeat on Guacamole": {
"entitySnapshot_properties": {
"_prioritySelection": "MEASURMENT",
"_prevKeyAttrMap": "-84.-19.0.5.115.114.0.19.106.97.118.97.46.117.116.105.108.46.65.114.114.97.121.76.105.115.116.120.-127.-46.29.-103.-57.97.-99.3.0.1.73.0.4.115.105.122.101.120.112.0.0.0.0.119.4.0.0.0.0.120.",
"_name": "Heartbeat on Guacamole",
"_frequency": "600",
"_externalId": "80c24825-c540-4e9d-8203-df83333e0a55",
"_reportTopology": "true",
"_eventPreferenceId": "CommonEventInstancePreferences_default",
"_ownerID": "1951498571"
},
"monitor_snapshot_hostName": "<hostname>",
"monitor_snapshot_fullyQualifiedTarget": "<hostFQDN>",
"entitySnapshot_name": "Heartbeat on Guacamole",
"snapshot_alertSnapshotChildren": {},
"entitySnapshot_url": ""
}
}
}
},
"entitySnapshot_name": "Test",
"snapshot_alertSnapshotChildren": {},
"entitySnapshot_url": "",
"snapshot_monitorSnapshotChildren": {}
}
},
"entitySnapshot_name": "SiteScopeRoot",
"snapshot_alertSnapshotChildren": {},
"snapshot_preferenceSnapShot": {},
"entitySnapshot_url": "",
"snapshot_monitorSnapshotChildren": {}
}
Here is my draft code for looping through, which returns an error that "snapshot_groupSnapshotChildren" dosent exist.
$info = Get-Content -Path .\input.json
If($info -eq $null){
Write-Host "Unhandled Exception parsing data for $sitescopeFQDNhost`nExit Script" -ForegroundColor Red -BackgroundColor Black
Exit
}
else{
$ResJsonObj = $info | ConvertFrom-Json #-Depth 99
foreach ($t in $ResJsonObj.PSObject.Properties)
{
Write-Host $t.name
Write-Host $t.value
}
}
Let me know how i can loop through the nested json file to strip out the atributes values under each "entitySnapshot_properties", I a intrested to fetch the following attribute values
Test -->_name, _class
2.Guacamole -->_name,_ownerid
Heartbeat on Guacamole --> _name,monitor_snapshot_hostName

Related

Powershell JSON Manipulation

$parent = #"
{
"Property1": "Property1Value",
"Description": "Generic Description",
"SubProperties": {
"SubSubTemplateProps": {
SubSubSubTemplateProps1 : "SubSubSubTemplateProps1",
SubSubSubTemplateProps2 : {
SubSubSubSubTemplateProps1 : [
{
"Key": "Name",
"Value": "Temp"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
}
}
}
"# | ConvertFrom-Json
$templateobj = $parent.SubProperties.SubSubTemplateProps
$parent.SubProperties.psobject.Properties.Remove("SubSubTemplateProps")
for($j = 0; $j -lt 3; $j++)
{
$i = "{0:D2}" -f ($j+1)
$letters = #("a","b","c")
foreach($letter in $letters)
{
$newobject = $templateobj
($newobject.SubSubSubTemplateProps2.SubSubSubSubTemplateProps1 | ? {$_.key -eq "Name"}).Value = "NewValue$letter$i"
$parent.SubProperties | Add-Member -MemberType NoteProperty -Name "SubSubProp$letter$i" -Value $newobject
}
}
$parent |convertto-json -Depth 100
Im expecting output like this:
{
"Property1": "Property1Value",
"Description": "Generic Description",
"SubProperties": {
"SubSubPropa01": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValuea01"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropb01": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb01"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropa02": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValuea02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropb02": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
}
}
}
But I get output like this where all of the noteproperties of the parent are updated instead of just the noteproperty I added. WHAT?!
{
"Property1": "Property1Value",
"Description": "Generic Description",
"SubProperties": {
"SubSubPropa01": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropb01": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropa02": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
},
"SubSubPropb02": {
"SubSubSubTemplateProps1": "SubSubSubTemplateProps1",
"SubSubSubTemplateProps2": {
"SubSubSubSubTemplateProps1": [
{
"Key": "Name",
"Value": "NewValueb02"
},
{
"Key": "SupSubSubProp2",
"Value": "Supprop2value"
}
]
}
}
}
}
Can someone suggest how to copy a node and replace a sub value then add it back to the parent without it overwriting all other child nodes? Not sure why this is happening.
The fundamental problem, as explained in the comments and in more detail in this related answer is:
[pscustomobject] instances, such as returned by ConvertFrom-Json are instances of a .NET reference type, which means that $newobject = $templateobj doesn't create a copy of the object stored in $templateobj in $newobject, it creates a copy of the reference to object $templateobj, so that $templateobj and $newobject end up pointing to the very same object. Only instances of .NET value types are themselves copied with simple assignments - see this answer for background information.
Therefore, you ended up repeatedly modifying the very same object instead of independent copies of it.
While $templateobj.psobject.Copy() is a convenient method to create a shallow clone (copy) of a [pscustomobject] instance, it isn't sufficient in your case, because your instances also contain reference-type instances among the object's property values, which then again get copies as references.
In other words: your template object is a [pscustomobject] graph (nested), so it requires deep-cloning, for which there is no built-in method.
Note: If you know the structure of the template object ahead of time, there are simpler and more efficient solutions:
Use a literal [pscustomobject] object definition inside your loop, which creates a new instance every time - see the related answer.
Construct your template as an ordered hashtable ([ordered] #{ ... }), and cast it to [pscustomobject] every time you need a new copy inside the loop - see this answer
Define a custom class and instantiate it in every loop iteration - see this answer.
If you do need deep-cloning of [pscustomobject] graphs, use helper function Copy-PSCustomObject, defined further below, with the -Deep switch:
$newobject = Copy-PSCustomObject -Deep $templateobj
Helper function Copy-PSCustomObject:
Note: This is not a generic deep-cloning function that works with objects of any type (which would be impossible to implement), but it should work with [pscustomobject] graphs such as returned by ConvertFrom-Json, which limits their composition to:
Primitive JSON types that map onto primitive .NET types and [string], all of which either are .NET value types or, in the case of [string] act like them.
Nested [pscustomobject] instances with the same composition.
Arrays of either.
function Copy-PSCustomObject {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[PSCustomObject] $InputObject,
[switch] $Deep
)
begin {
if ($Deep) {
# Helper script block (anonymous function) for walking the object graph
$sb = {
param($original)
$copy = $original.psobject.Copy()
foreach ($prop in $copy.psobject.Properties) {
if ($prop.Value -is [System.Collections.IEnumerable]) { # Presumed array
$prop.Value = #($prop.Value) # Clone array
foreach ($i in 0..($prop.Value.Count-1)) {
$prop.Value[$i] = & $sb $prop.Value[$i] # Recurse
}
}
elseif ($prop.Value -is [System.Management.Automation.PSCustomObject]) {
$prop.Value = & $sb $prop.Value # Recurse
}
# Otherwise: assume it is a value type or string and needs no cloning.
}
# Output the deep-cloned object
$copy
}
}
}
process {
if ($Deep) {
& $sb $InputObject
}
else {
# Shallow copy.
$InputObject.psobject.Copy()
}
}
}

powershell json format variable in tmsl script

I use powershell and i want to put variable in json format into TMSL create role script. I want to put this variable into TablePermission parameter
json variable:
$filter=
[
{
"name": "DimGeography",
"filterExpression": "DimGeography[CountryRegionCode] = \"US\" "
}
]
TMSL script:
$Query='
{
"create": {
"parentObject": {
"database": "AW Internet Sales"
},
"role": {
"name": "test_filter",
"modelPermission": "read",
"tablePermissions": "'+$filter+'"
}
}
}'
This is script which I want to parametrize
{
"createOrReplace": {
"object": {
"database": "AW Internet Sales",
"role": "SalesManagerUS"
},
"role": {
"name": "SalesManagerUS",
"modelPermission": "read",
"tablePermissions": [
{
"name": "DimGeography",
"filterExpression": "DimGeography[CountryRegionCode] = \"US\" "
}
]
}
}
}
How can I put $filter to $Query to receive working script like above ?
You could try the below snippet :
$filter=
'[
{
"name": "DimGeography",
"filterExpression": "DimGeography[CountryRegionCode] = \"US\" "
}
]'
function populate-tsml ($filter)
{
$Query='
{
"create": {
"parentObject": {
"database": "AW Internet Sales"
},
"role": {
"name": "test_filter",
"modelPermission": "read",
"tablePermissions": '+$filter+'
}
}
}'
return $Query
}
$Query = populate-tsml -filter $filter
OUTPUT :
Thank you!
It wasn't necesseary to define a function, a little changes in quotation marks was enough.
Script below works:
$filter=
'[
{
"name": "DimGeography",
"filterExpression": "DimGeography[CountryRegionCode] = \"US\" "
}
]'
$Query='
{
"create": {
"parentObject": {
"database": "AW Internet Sales"
},
"role": {
"name": "test_filter",
"modelPermission": "read",
"tablePermissions": '+$filter+'
}
}
}'

Need to convert nested Json response to csv in powershell

I have below sample nested json response and I need to convert this response with specific values into CSV file. Below is the sample nested Json response:
{
"transaction": {
"id": "TestTransID",
"testCode": "NEW",
"TestStatus": "SUCCESS",
"client": {
"TestNumber": "112112111"
},
"subject": {
"individual": {
"additionalAttributes": {
"extraid": "787877878"
},
"addressList": [
{
"city": "New York",
"country": {
"name": "United States"
},
"postalCode": "123456789",
"stateOrProvince": {
"codeValue": "NY"
}
}
],
"gender": "F",
"identificationDocumentList": [
{
"number": "1214558520",
"type": "TestId"
}
],
"name": {
"firstName": "Qusay TestFull",
"lastName": "TestLast",
"middleName": "Middle 3"
}
}
},
"PROCESSConfiguration": {
"id": 1
},
"testProductList": [
{
"product": {
"id": 00,
"name": "Test PROCESS",
"productCode": "EFG",
"disclaimer": "TestDisclaimer"
},
"testSourceResponseList": [
{
"testSource": {
"id": 1,
"name": "TEST"
},
"testSourceRecordList": [
{
"type": "TestRecord",
"alertReasonCode": "TESTS",
"alertReasonDescription": "ACTION LIST HIT - TEST",
"testSource": "TEST",
"varListNameFull": "TEST FULL NAME",
"varListNameShort": "TEST SHORT",
"varProgList": [
"SHORT"
],
"varListId": "3421",
"subject": {
"individual": {
"TestScore": {
"TestScore": 100,
"triggeredRule": "TestRule"
},
"aNameList": [
{
"fullName": " TestNameA",
"lastName": "TestNameA"
},
{
"firstName": "TestFirst",
"fullName": "TestFirst HUSAYN",
"lastName": "TestLast"
},
{
"firstName": "TestFirst",
"fullName": "TestFull",
"lastName": "TestLast"
},
{
"firstName": "TestFirst",
"fullName": "TestFull",
"lastName": "TestLast"
}
],
"birthList": [
{
"dateOfBirth": "12 Apr 1910",
"dateOfBirthVerified": "true"
}
],
"name": {
"firstName": "TestFirst",
"fullName": "TestFull",
"lastName": "TestLast"
},
"varNationality": [
{
"verified": "true"
}
],
"remarks": "remark1"
}
}
},
{
"testSource": "TEST",
"varListNameFull": "TEST FULL",
"varListNameShort": "TEST SHORT",
"varProgList": [
"XYZ"
],
"varListId": "1234",
"subject": {
"individual": {
"overallScore": {
"TestScore": 100,
"triggeredRule": "Testing"
},
"birthList": [
{
"dateOfBirth": "1965",
},
{
"dateOfBirth": "1966",
}
],
"name": {
"firstName": "TestFirst",
"fullName": "TestFull",
"lastName": "TestLast",
},
"varNationality": [
{
"verified": "true"
}
],
"remarks": "REMARK2"
}
}
}
]
}
]
}
],
}
}
I need to take response from ""PROCESSConfiguration": {
"id": 1"
from row # 40. If u'll take above code in notepad ++.
Also I need the response with respect to var value like first name, last name full name, DOB etc.
I am still unsure what is being asked for. Let me assume that you want a fully qualified path for each of the elements in the JSON file.
I started by making some small adjustments to the JSON based on http://jsonlint.com/.
Based on that, I did a proof of concept that works for ONE OBJECT like the JSON you posted. It works for THIS CASE. I wrapped the logic to deal with multiple objects making assumptions about when one object started and the next began. Also, logic would should be added to deal with nested series/array containing multiple properties (i.e. Threads in Get-Process) to handle a generic case. A single element with an array of values (like .transaction.varProgList in this case) is handled by putting a ‘;’ between them.
CSV files assume that all the objects are symmetric (have the same properties). There is no check to see that the properties for each object align with the properties of the other objects. Note the handling of nested series is related to this. You may see an example of this by uncommenting the [System.Collections.ICollection] section and trying something like (Get-Process r*) | Select-Object Name,Threads | Expand-NestedProperty | Out-File .\t.csv -Width 100000
The repro goes as follows where $a is the adjusted JSON content and the function is saved as Expand-NestedProperty.ps1.
# Load the function
. .\Expand-NestedProperty.ps1
# Create PowerShell object(s) based on the JSON
$b = $a | ConvertFrom-Json
# Create a file with the CSV contents.
$b | Expand-NestedProperty | Out-File -FilePath .\my.csv -Width 100000
Save this as Expand-NestedProperty.ps1
function Expand-NestedProperty {
[CmdletBinding()]
param (
[Parameter( Position=0,
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
HelpMessage='Object required...' )]
$InputObject
)
begin {
function ExpandNestedProperty {
[CmdletBinding()]
param (
[Parameter( Position=0,
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
HelpMessage='Object required...' )]
$InputObject,
[Parameter( Position=1,
Mandatory=$false,
ValueFromPipeline=$false,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
HelpMessage='String required...' )]
[string]
$FullyQualifiedName = ""
)
begin {
$localResults =#()
$FQN = $FullyQualifiedName
$nestedProperties = $null
}
process {
foreach ($obj in $InputObject.psobject.Properties) {
if ($(try {$obj.Value[0] -is [PSCustomObject]} catch {$false})) { # Catch 'Cannot index into a null array' for null values
# Nested properties
$FQN = "$($FullyQualifiedName).$($obj.Name)"
$nestedProperties = $obj.value | ExpandNestedProperty -FullyQualifiedName $FQN
}
elseif ($obj.Value -is [array]) {
# Array property
$FQN = "$($FullyQualifiedName).$($obj.Name)"
[psobject]$nestedProperties = #{
$FQN = ($obj.Value -join ';')
}
}
# Example of how to deal with generic case.
# This needed for the Get-Process values ([System.Collections.ReadOnlyCollectionBase] and [System.Diagnostics.FileVersionInfo]) that are not [array] collection type.
<#
elseif ($obj.Value -is [System.Collections.ICollection]) {
# Nested properties
$FQN = "$($FullyQualifiedName).$($obj.Name)"
$nestedProperties = $obj.value | ExpandNestedProperty -FullyQualifiedName $FQN
}
#>
else { # ($obj -is [PSNoteProperty]) for this case, but could be any type
$FQN = "$($FullyQualifiedName).$($obj.Name)"
[psobject]$nestedProperties = #{
$FQN = $obj.Value
}
}
$localResults += $nestedProperties
} #foreach $obj
}
end {
[pscustomobject]$localResults
}
} # function ExpandNestedProperty
$objectNumber = 0
$firstObject = #()
$otherObjects = #()
}
process {
if ($objectNumber -eq 0) {
$objectNumber++
$firstObject = $InputObject[0] | ExpandNestedProperty
}
else {
if ($InputObject -is [array]) {
foreach ($nextInputObject in $InputObject[1..-1]) {
$objectNumber++
$otherObjects += ,($nextInputObject | ExpandNestedProperty)
}
}
else {
$objectNumber++
$otherObjects += ,($InputObject | ExpandNestedProperty)
}
}
}
end {
# Output CSV header and a line for each object which was the specific requirement here.
# Could create an array of objects using $firstObject + $otherObjects that is then piped to Export-CSV if we want a generic case.
Write-Output "`"$($firstObject.Keys -join '","')`""
Write-Output "`"$($firstObject.Values -join '","')`""
foreach ($otherObject in $otherObjects) {
Write-Output "`"$($otherObject.Values -join '","')`""
}
}
} # function Expand-NestedProperty

How to delete a Json object from Json File by sed command in BASH

I a have a JSON file in which a JSON object needs to be deleted.
Is there any way to delete it by using the sed command only?
My sample file is given below.
{
"name": "ABC",
"description": "XYZ",
"versions": {},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {},
"override_attributes": {
"company": {
"xyz": {
"mailer": {
"smtp_host": "Some IP",
"imap_host": "Some Host",
"imap_user": "Some UserId",
"reply_to": "Some User Id",
"outbound_user": "",
"imap_mail_domain": "compute.oraclecloud.com",
"imap_password": ""
},
"logicaldomainname": ""
}
}
}
}
I want to delete the mailer object from the file using the sed command.
Please take a look and let me know if it is possible using the sed command.
My main motive of this deletion is to replace this object with new
mailer object so that the next time when another mailer object will be posted then we will append it in xyz JSON object.
Expected output:
{
"name": "ABC",
"description": "",
"version": {},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {},
"override_attributes": {
"Company": {
"XYZ": {
"logicaldomainname": ""
}
}
}
}
Using sed:
sed '/\"mailer\"/,/}/ d; /^$/d' 1.a
"Delete from mailer to the first }, then delete all blank lines (you input has one)".
To overwrite the file ("in-place")
sed -i ...
Note: works for multiline files (as yours).
You should strongly consider resolving the licensing issue that prohibits jq:
jq 'del(.override_attributes.company.xyz.mailer) | .description=""' input.json
$ awk -v RS='^$' -v ORS= '{sub(/"mailer":[^}]+},[[:space:]]+/,"")}1' file
{
"name": "ABC",
"description": "",
"versions": {
},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {
},
"override_attributes": {
"Company": {
"XYZ": {
"logicaldomainname": ""
}
}
}
}
The above uses GNU awk for multi-char RS, with other awks you'd build up the record one line at a time and handle it in the END section:
$ awk -v ORS= '{rec=rec $0 RS} END{sub(/"mailer":[^}]+},[[:space:]]+/,"",rec); print rec}' file
{
"name": "ABC",
"description": "",
"versions": {
},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {
},
"override_attributes": {
"Company": {
"XYZ": {
"logicaldomainname": ""
}
}
}
}

Storing a part of a json query result in a variable in powershell

I have the following output from a json query and I am looking for a way to search though it and pull the value for the tvdbid(the number 72663) and store it in a variable.
In the example below you can see there are actually 2 results so I would like it to store the both in array.
I am running powershell 3 on my pc so any v3 specific stuff should be ok.
Out put
{
"data": {
"langid": 7,
"results": [
{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}
]
},
"message": "",
"result": "success"
}
Using PS V3:
$json = #'
{
"data": {
"langid": 7,
"results": [
{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}
]
},
"message": "",
"result": "success"
}
'#
$psobj = ConvertFrom-Json $json
$psobj.data.results.tvdbid
72663
135881
Most of the time I use now the CmdLet given by #mjolinor, but I still use the following old fashion XML serialization in two cases :
1- When I must use PowerShell V2
2- Even in PowerShell V3 when the json returned by a web service is very big the PowerShell V3 is sending an exception.
Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
$utf8 = [System.Text.Encoding]::UTF8
function Write-String
{
PARAM([Parameter()]$stream,
[Parameter(ValueFromPipeline=$true)]$string)
PROCESS
{
$bytes = $utf8.GetBytes($string)
$stream.Write( $bytes, 0, $bytes.Length )
}
}
function Convert-JsonToXml
{
PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
BEGIN
{
$mStream = New-Object System.IO.MemoryStream
}
PROCESS
{
$json | Write-String -stream $mStream
}
END
{
$mStream.Position = 0
try
{
$jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
$xml = New-Object Xml.XmlDocument
$xml.Load($jsonReader)
$xml
}
finally
{
$jsonReader.Close()
$mStream.Dispose()
}
}
}
function Convert-XmlToJson
{
PARAM([Parameter(ValueFromPipeline=$true)][Xml]$xml)
PROCESS
{
$mStream = New-Object System.IO.MemoryStream
$jsonWriter = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonWriter($mStream)
try
{
$xml.Save($jsonWriter)
$bytes = $mStream.ToArray()
[System.Text.Encoding]::UTF8.GetString($bytes,0,$bytes.Length)
}
finally
{
$jsonWriter.Close()
$mStream.Dispose()
}
}
}
In your case this will give the following :
$json = #'
{
"data": {
"langid": 7,
"results": [{
"first_aired": "2010-11-15",
"name": "Accused",
"tvdbid": 72663
},
{
"first_aired": "2010-01-17",
"name": "Enzai: Falsely Accused",
"tvdbid": 135881
}]
},
"message": "",
"result": "success"
}
'#
$xmlOut = Convert-JsonToXml -json $json
($xmlOut.root.data.results).ChildNodes[0].tvdbid.InnerText
($xmlOut.root.data.results).ChildNodes[1].tvdbid.InnerText