-
Notifications
You must be signed in to change notification settings - Fork 29
/
Export-Json.ps1
117 lines (101 loc) · 3.58 KB
/
Export-Json.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<#
.SYNOPSIS
Exports a portion of a JSON document, recursively importing references.
.INPUTS
System.String containing JSON, or
System.Collections.Hashtable parsed from JSON, or
System.Management.Automation.PSObject parsed from JSON.
.OUTPUTS
System.String containing the extracted JSON.
.FUNCTIONALITY
Json
.LINK
http://jsonref.org/
.LINK
https://www.rfc-editor.org/rfc/rfc6901
.LINK
https://github.com/MicrosoftDocs/PowerShell-Docs/pull/9042
.LINK
Select-Json.ps1
.EXAMPLE
'{d:{a:{b:1,c:{"$ref":"#/d/two"}},two:2}}' |Export-Json.ps1 /d/a
{
"b": 1,
"c": 2
}
.EXAMPLE
'{d:{a:{b:1,c:{"$ref":"#/d/c"}},c:{d:{"$ref":"#/d/two"}},two:2}}' |Export-Json.ps1 /d/a -Compress
{"b":1,"c":{"d":2}}
#>
#Requires -Version 7
[CmdletBinding()][OutputType([string])] Param(
<#
The full path name of the property to get, as a JSON Pointer, modified to support wildcards:
~0 = ~ ~1 = / ~2 = ? ~3 = * ~4 = [
#>
[Parameter(Position=0)][Alias('Name')][AllowEmptyString()][ValidatePattern('\A(?:|/(?:[^~]|~[0-4])*)\z')]
[string] $JsonPointer = '',
# The JSON (string or parsed object/hashtable) to get the value from.
[Parameter(ParameterSetName='InputObject',ValueFromPipeline=$true)] $InputObject,
# A JSON file to update.
[Parameter(ParameterSetName='Path',Mandatory=$true)][string] $Path,
# Omits white space and indented formatting in the output string.
[switch] $Compress
)
Begin
{
if($PSVersionTable.PSVersion -lt 7.3) {Write-Warning "JSON property order may be changed in PowerShell < 7.3"}
function Get-Reference
{
[CmdletBinding()] Param([uri] $ReferenceUri, $Root)
$source,$pointer = switch($ReferenceUri)
{
{$_.OriginalString -like '#*'} {$Root,($_.OriginalString -replace '\A#')}
{$_.IsFile} {(Get-Content $_.LocalPath -Raw |ConvertFrom-Json -AsHashtable),($_.Fragment -replace '\A*')}
default {(Invoke-RestMethod $ReferenceUri),($_.Fragment -replace '\A#')}
}
return $source |Select-Json.ps1 $pointer |Import-Reference -Root $source
}
filter Import-Reference
{
[CmdletBinding()] Param($Root, [Parameter(ValueFromPipeline=$true)] $InputObject)
if($null -eq $InputObject -or $InputObject -is [bool] -or $InputObject -is [long] -or
$InputObject -is [double] -or $InputObject -is [string]) {return $InputObject}
if(($InputObject |ConvertTo-Json -Compress -Depth 100) -notlike '*"$ref":*') {return $InputObject}
if($InputObject -is [Collections.IList]) {return ,@($InputObject |Import-Reference -Root $Root)}
if($InputObject -is [Collections.IDictionary])
{
if($InputObject.ContainsKey('$ref'))
{
return Get-Reference -ReferenceUri $InputObject['$ref'] -Root $Root
}
foreach($name in @($InputObject.Keys))
{
$InputObject[$name] = Import-Reference -Root $Root -InputObject $InputObject[$name]
}
return $InputObject
}
if($InputObject.PSObject.Properties.Match('$ref').Count)
{
return Get-Reference -ReferenceUri ($InputObject.'$ref') -Root $Root
}
foreach($property in $InputObject.PSObject.Properties)
{
$name = $property.Name
$InputObject.$name = Import-Reference -Root $Root -InputObject ($InputObject.$name)
}
return $InputObject
}
if($Path)
{
return Resolve-Path -Path $Path |
ForEach-Object {$_ |Get-Content -Raw |
Export-Json.ps1 -JsonPointer $JsonPointer -Compress:$Compress}
}
}
End
{
$root = $InputObject -is [string] ? ($InputObject |ConvertFrom-Json -AsHashtable) : $InputObject
$selection = $root |Select-Json.ps1 $JsonPointer
return $selection |Import-Reference -Root $root |ConvertTo-Json -Depth 100 -Compress:$Compress
}