Okay, so our last thing to focus on here is the loading
and iterating of both XML and JSON data.
Now there are some common commands available to us in PowerShell.
We don't have to write everything.
I know that we're talking about writing PowerShell scripts,
but we can use existing cmdlets to help us here.
The first one is ConvertTo‑Xml. This cmdlet creates an XML‑based
representation of one or more .NET objects.
We also, then have ConvertFrom‑Json, which will basically
convert a JSON‑formatted string to a custom object, or we
can pipe that out to a hash table.
We also, then have the ConvertTo‑Json,
which will convert whatever the object is we've
chosen to a JSON‑formatted string.
Now to load XML, the simplest approach is to use the SELECT‑XML command.
It uses an XPath query to search for text in the XML strings and/or documents,
and it requires the path of the XML file and the XPath within the XML
document to be able to search for specific values.
So from a simple perspective, we pass a path, and we choose the XPath.
Now you would need to know this.
So I define two variables.
One is $path which goes to my Countries.xml, and then my
$xpath, if I was to look at my XML definition,
and I clearly have Countries as an XML option, Country, and then Name.
So that's my $xpath.
If I want to retrieve those values and load it,
I simply say Select‑Xml, pass in the ‑Path, which will be the file, and the
‑Xpath, which is the place where the data is in the XML document I wish to
retrieve. Now if I wanted to iterate and retrieve XML data, so let's go
back to kind of the same idea, I've got some XPath information here and a
path. So my $path will be Countries‑with‑Attributes, which has a list of
countries plus some of the values, and then $xpath, which will be
/Countries/Country.
So if you think of this logically,
my XML document must have countries and then each
country listed. To retrieve that,
I'm going to say load the XML data first into an XML variable.
So Select‑Xml ‑Path is the $path.
‑Xpath is the $xpath I wish to reiterate. And then we can loop, and
it's as simple as saying here's my XML object, pipe it into
ForEach‑Object, and then say $_.Node.name, and that will iterate
just the named values that we're iterating. Now we could also do
this differently and say, well, actually,
what I'd like to do is just load it as a big object and not have to
use the XPath. So I can define a variable as xml.
You'll see [xml] and the variable.
Then use an out‑of‑the‑box cmdlet called Get‑Content
and pass the path of the XML file.
At that point,
I have to know the path to get the value. So you would have to look at it
and say, okay, $xml.Countries.Country.Name.Population. So what are the
steps for iterating through XML data? Well,
the first one is to read the file and cast it directly to an XML object.
That's the first step.
Second one is then to iterate through the XML data,
and then the third is to return the results of that iteration.
So, as an example,
let's imagine that we have an XML file with countries with some checked values.
If I wanted to retrieve and iterate and write values out,
then we could create something like this. So you can see, we're creating an
XML object. We're getting the content from that path.
What I'm then doing is instead of me trying to iterate through all of it,
I'm going to say $xml, which is my now full XML file, .Countries.Country.
So I want to iterate every country. So once I've got that as an object,
I'm going to pipe that into a where object,
which is where I'm looking for a field property in that
XML file, which is called Validated, and it's equal to True.
Once I've got that, I basically have an array of values,
which means that I can then foreach loop at that point.
So I'm going to say, ForEach‑Object,
go and create me a PSCustomObject, and get me the values out.
So, this allows me to retrieve data from XML,
identify without having to use an XPath, and then
populate that into a PSCustomObject.
Now working with JSON is a little bit more popular as JSON is
very lightweight. Now working with JSON,
we have the ability to import the JSON.
We can also export JSON, and we can, of course,
test JSON, so very much like working with XML. Now to
import a JSON file, we simply have a path, so you can see
I've got a list of countries again,
but they're in a JSON format. And we use the same thing where we say
Get‑Content into a variable, but you're using one of the predetermined and
created cmdlets called ConvertFrom‑JSON. That cmdlet will take the JSON and be
able to load it as the format that's required.
If I wanted to export it, whatever the JSON or the variable contained,
I can use ConvertTo‑JSON, and then I'm piping that value
to an Out‑File in a specific path.
If I wanted to test it,
I could get the content to a path, so my Countries.json, and then I can
pipe that into Test‑JSON that will validate that that structure is actual
JSON. And you need to remember, that's quite important to do because too
often people are moving JSON data around.
It contains characters that doesn't quite work, and so it fails in execution.
So you should always test your JSON. Now if I want to iterate and
retrieve JSON, so we have our variable very much like XML, so we have a
variable called $path to a JSON file, you can see what I'm doing here is
go $json, get the content to the path. use the ConvertFrom‑JSON, and
then it works like XML. I can say $json.Countries, and it will iterate
the countries for me.
I could also use a standard Foreach loop by just saying for every
item in the JSON, and then I have to kind of know the path a
little bit, so $item.Countries.Country, and then select the
object that I want to display.
And then, of course, I can use a Foreach with what's called an expand.
Now ‑ExpandProperty will take a specific value and allow
me to kind of pop that value open,
allowing me access to the values that reside inside that.
So if you think about it,
if I do $item.Countries, that will list me all of the countries,
but not the properties that reside inside the country.
So if I do Select‑Object ‑ExpandProperty Country, and then pipe it out,
that means I now get access to Name and Population.
Now we also have the ability in PowerShell to
retrieve JSON from other RESTful APIs.
So there's a public set of APIs at swapi.dev, and one of them is called people.
And to do this,
I'm going to load a variable called $json, use what's called
Invoke‑RestMethod, pass in the URI or the URL to that one.
This will then return a set of results,
which I can then use a standard for each. Now notice the
difference here. When you're using a RESTful API,
there's always a results object that comes back.
So I'm going to say Foreach item, so the item in the
$json.results. And then because it's JSON,
I get the object of $item and then pass it to a selector to be able to say Name, Height, and Gender.