@@ -8,7 +8,7 @@ function Get-JsonLD {
88 This is a format used by many websites to provide structured data about their content.
99 . EXAMPLE
1010 # Want to get information about a movie? Linked Data to the rescue!
11- Get-JsonLD -Url https://www.imdb. com/title/tt0211915 /
11+ Get-JsonLD -Url https://letterboxd. com/film/amelie /
1212 . EXAMPLE
1313 # Want information about an article? Lots of news sites use this format.
1414 Get-JsonLD https://www.thebulwark.com/p/mahmoud-khalil-immigration-detention-first-amendment-free-speech-rights
@@ -21,9 +21,30 @@ function Get-JsonLD {
2121 param (
2222 # The URL that may contain JSON-LD data
2323 [Parameter (Mandatory , ValueFromPipeline , ValueFromPipelineByPropertyName )]
24+ [Alias (' href' )]
2425 [Uri ]
2526 $Url ,
2627
28+ <#
29+
30+ If set, will the output as:
31+
32+ |as|is|
33+ |-|-|
34+ |html|the response as text|
35+ |json|the match as json|
36+ |*jsonld`|ld`|linkedData*|the match as linked data|'
37+ |script|the script tag|
38+ |xml|the script tag, as xml|
39+
40+ #>
41+ [ValidateSet (' html' , ' json' , ' jsonld' , ' ld' , ' linkedData' , ' script' , ' xml' )]
42+ [string ]
43+ $as = ' jsonld' ,
44+
45+ [switch ]
46+ $RawHtml ,
47+
2748 # If set, will force the request to be made even if the URL has already been cached.
2849 [switch ]
2950 $Force
@@ -46,39 +67,146 @@ application/ld\+json # The type that indicates linked d
4667'@ , ' IgnoreCase,IgnorePatternWhitespace' , ' 00:00:00.1' )
4768
4869 # Initialize the cache for JSON-LD requests
49- if (-not $script :JsonLDRequestCache ) {
50- $script :JsonLDRequestCache = [Ordered ]@ {}
70+ if (-not $script :Cache ) {
71+ $script :Cache = [Ordered ]@ {}
72+ }
73+
74+ filter output {
75+ $in = $_
76+ $mySelf = $MyInvocation.MyCommand
77+ if ($in .' @context' -is [string ]) {
78+ $context = $in .' @context'
79+ }
80+ if ($in .' @graph' ) {
81+ if ($in.pstypenames -ne ' application/ld+json' ) {
82+ $in.pstypenames.insert (0 , ' application/ld+json' )
83+ }
84+ foreach ($graphObject in $in .' @graph' ) {
85+ $null = $graphObject |
86+ & $mySelf
87+ }
88+ }
89+ elseif ($in .' @type' ) {
90+
91+ $typeName = if ($context ) {
92+ $context , $in .' @type' -join ' /'
93+ } else {
94+ $in .' @type'
95+ }
96+
97+ if ($in.pstypenames -ne ' application/ld+json' ) {
98+ $in.pstypenames.insert (0 , ' application/ld+json' )
99+ }
100+ if ($in.pstypenames -ne $typeName ) {
101+ $in.pstypenames.insert (0 , $typeName )
102+ }
103+
104+ foreach ($property in $in.psobject.properties ) {
105+ if ($property.value .' @type' ) {
106+ $null = $property.value |
107+ & $mySelf
108+ }
109+ }
110+ }
111+ $in
112+ }
113+
114+ $foreachFile = {
115+ $inFile = $_.FullName
116+ try {
117+
118+ Get-Content - LiteralPath $_.FullName - Raw |
119+ ConvertFrom-Json |
120+ output
121+ } catch {
122+ Write-Verbose " $ ( $inFile.FullName ) : $_ "
123+ }
51124 }
52125 }
53126
54127 process {
128+ if ($url.IsFile -or
129+ -not $url.AbsoluteUri
130+ ) {
131+ if (Test-Path $url.OriginalString ) {
132+ Get-ChildItem $url.OriginalString - File |
133+ Foreach-Object $foreachFile
134+ } elseif ($MyInvocation.MyCommand.Module -and
135+ (Test-Path (
136+ Join-Path (
137+ $MyInvocation.MyCommand.Module | Split-Path
138+ ) $url.OriginalString
139+ ))
140+ ) {
141+ Get-ChildItem - Path (
142+ Join-Path (
143+ $MyInvocation.MyCommand.Module | Split-Path
144+ ) $url.OriginalString
145+ ) - File |
146+ Foreach-Object $foreachFile
147+ }
148+
149+ return
150+ }
151+
55152 $restResponse =
56- if ($Force -or -not $script :JsonLDRequestCache [$url ]) {
57- $script :JsonLDRequestCache [$url ] = Invoke-RestMethod - Uri $Url
58- $script :JsonLDRequestCache [$url ]
153+ if ($Force -or -not $script :Cache [$url ]) {
154+ $script :Cache [$url ] = Invoke-RestMethod - Uri $Url
155+ $script :Cache [$url ]
59156 } else {
60- $script :JsonLDRequestCache [$url ]
157+ $script :Cache [$url ]
61158 }
159+
160+ if ($as -eq ' html' ) {
161+ return $restResponse
162+ }
163+
164+ # Find all linked data tags within the response
62165 foreach ($match in $linkedDataRegex.Matches (" $restResponse " )) {
166+ # If we want the result as xml
167+ if ($As -eq ' xml' ) {
168+ # try to cast it
169+ $matchXml = " $match " -as [xml ]
170+ if ($matchXml ) {
171+ # and output it if found.
172+ $matchXml
173+ continue
174+ } else {
175+ # otherwise, fall back to the `<script>` tag
176+ $As = ' script'
177+ }
178+ }
179+
180+ # If we want the tag, that should be the whole match
181+ if ($As -eq ' script' ) {
182+ " $match "
183+ continue
184+ }
185+
186+ # If we want it as json, we have a match group.
187+ if ($As -eq ' json' ) {
188+ $match.Groups [' JsonContent' ].Value
189+ continue
190+ }
191+ # Otherwise, we want it as linked data, so convert from the json
63192 foreach ($jsonObject in
64193 $match.Groups [' JsonContent' ].Value |
65194 ConvertFrom-Json
66195 ) {
67- if ($jsonObject .' @type' ) {
68- $schemaType = $jsonObject .' @context' , $jsonObject .' @type' -ne ' ' -join ' /'
69- $jsonObject.pstypenames.insert (0 , $schemaType )
196+ # If there was a `@type` or `@graph` property
197+ if (
198+ $jsonObject .' @type' -or
199+ $jsonObject .' @graph'
200+ ) {
201+ # output the object as jsonld
202+ $jsonObject | output
203+ continue
204+ }
205+ # If there is neither a `@type` or a `@graph`
206+ else {
207+ # just output the object.
70208 $jsonObject
71- } elseif ($jsonObject .' @graph' ) {
72- foreach ($graphObject in $jsonObject .' @graph' ) {
73- if ($graphObject .' @type' ) {
74- $graphObject.pstypenames.insert (0 , $graphObject .' @type' )
75- }
76- $graphObject
77- }
78- } else {
79- $jsonObject
80- }
81-
209+ }
82210 }
83211 }
84212 }
0 commit comments