XML is all over the place. Despite its annoying utilise of angle brackets, XML format is however widely used. Configuration files, RSS feeds, Function files (the 'x' in the .docx) are just a partial list. Using PowerShell to parse XML files is an essential step in your PowerShell journey.
This tutorial will show you how PowerShell parse XML files and validate them. This will walk you from zilch to hero for all aspects of getting and evaluating XML data. You will be given tools that will help you validate XML data integrity and stop faulty data correct at the gate of your scripts!
Prerequisites
To follow along with the presented cloth, you should have:
PowerShell version 3.0 and above. The examples were created on Windows PowerShell v5.i
Notepad++, Visual Studio Lawmaking or another text editor that understands XML.
Parsing Powershell XML Elements with Select-Xml
Let's first encompass one of the virtually popular and easiest means to use PowerShell to parse XML and that's with Select-Xml. The Select-Xml cmdlet allows you to provide an XML file or cord along with a "filter" known as XPath to pull out specific data.
XPath is a chain of element names. It uses a "path like" syntax to identify and navigate nodes in an XML certificate.
Permit'southward say yous accept an XML file with a agglomeration of computers and would like to utilise PowerShell to parse this XML file. Each reckoner has various elements like name, IP address and an Include element for inclusion in a report.
An chemical element is an XML portion with an opening tag and a endmost tag, perchance with some text in-between, such as <Name>SRV-01</Name>
You'd like to utilize PowerShell to parse this XML file get the figurer names. To do that, you could use the Select-Xml command.
In the file above, the computer names appear in the inner text (InnerXML) of the Name element.
InnerXML is the text between the two chemical element'southward tags.
To find the computer names, you'd kickoff provide the appropriate XPath (/Computers/Computer/Proper name). This XPath syntax would return simply the Proper name nodes under the Computer elements. So to only get the InnerXML of each Name element, accomplish the Node.InnerXML property on each chemical element with a ForEach-Object loop.
Using PowerShell to Parse XML Attributes with Select-Xml
At present allow's address this problem of finding reckoner names from a different bending. This time, instead of the reckoner descriptors represented with XML elements, they are represented with XML attributes.
An attribute is a central/value portion such every bit name="SRV-01" . Attributes always appear within the opening tag, right after the tag name.
Below is the XML file with computer descriptors represented with attributes. You can now come across each descriptor every bit an aspect rather than an element.
Since each descriptor is an aspect this time, tweak the XPath a little bit to just observe the Computer elements. Then, using a ForEach-Object cmdlet again, find the value of the proper name aspect.
And indeed, this besides brings the same results: SRV-01, SRV-02 and SRV-03 :
In both cases, whether you lot are reading elements or attributes, the syntax of Select-Xml is cumbersome: it forces y'all to use the XPath parameter, then to pipe the result to a loop, and finally to look for the data under the Node property.
Luckily, PowerShell offers a more convenient and intuitive way to read XML files. PowerShell lets you lot read XML files and catechumen them to XML objects.
Related: Using PowerShell Data Types Accelerators to Speed up Coding
Casting XML Strings to Objects
Another style to apply PowerShell to parse XML is to convert that XML to objects. The easiest way to do this is with the [xml] blazon accelerator.
By prefixing the variable names with [xml], PowerShell converts the original plain text XML into objects you tin then piece of work with.
Now both the $xmlElm and $xmlAttr variables are XML objects allowing you to reference properties via dot annotation. Perchance yous need to find the IP accost of each computer element. Since the XML file is an object, you can so past simply referencing the IP chemical element.
$xmlElm.Computers.Computer.ip
Starting from PowerShell version 3.0, the XML object gets the attribute value with the aforementioned syntax used for reading the element's inner text. Therefore, the IP addresses' values are read from the attributes file with the exactly same syntax as the elements file.
Reading XML Attributes
Using exactly the same dot notation, you tin read XML attributes equally well despite differences in the XML structure.
And the results below show that both got the same data, each one from its corresponding file:
Moreover, with the object, once information technology is loaded to memory, you lot fifty-fifty go IntelliSense to tab-complete if y'all're using the PowerShell ISE. For instance as shown below.
Iterating Through XML Data
In one case you get effectually reading XML files directly to XML object (past taking advantage of the [xml] type accelerator), you have all the total ability of PowerShell objects.
Say, for case, you lot are required to loop through all the computers that appear in the XML file with the include="true" aspect to check their connection condition. The code below shows how information technology can be done.
This script is:
Reading the file and casting it to an XML object.
Iterating through the relevant computers to get their connexion status.
Finally, sending the result output object to the pipeline.
## casting the file text to an XML object [xml]$xmlAttr = Become-Content -Path C:\Work\computers-attr.xml ## looping through computers set with include="true" $xmlAttr.Computers.Figurer | Where-Object include -eq 'true' | ForEach-Object { ## see if the current computer is online if(Examination-Connection -ComputerName $_.ip -Count 1 -Quiet) { $condition = 'Connectedness OK' } else { $status = 'No Connexion' } ## output the effect object [pscustomobject]@{ Name = $_.name Ip = $_.ip Condition = $status } }
And the results of the script above are shown below:
XML Schemas
In the previous section, you saw 2 different XML files representing a data set in ii different ways. Those ways are chosen XML schemas. An XML Schema defines the legal edifice blocks of a specific XML document:
The names of elements and attributes that can appear in that specific document.
The number and order of kid elements.
The data types for elements and attributes.
The schema essentially defines the construction of the XML.
Validating XML Data
An XML file may take the correct syntax (editors similar Notepad++ will complain if not), yet its data might non lucifer the project requirement. This is where the schema comes in to play. When you lean on XML data, you lot must ensure thatall the data is valid according to the defined schema.
The concluding thing you want is to discover information errors in runtime, 500 lines deep in the script'southward heart. It might have already performed some irreversible operations on the file organization and the registry, by that time.
And then, how can you check in advance that the data is correct? Let's run across showtime some possible error types.
Possible Errors in XML Information
Generally speaking, errors found on XML files belong to 1 of two categories; metadata errors and errors in the data itself.
XML Metadata Errors
This file MorePeople.xml beneath, is perfectly valid syntax-wise. You can see below that the file has a unmarried People element (the root element) with three Person elements within. This structure is perfectly adequate. Still, it contains one exception, can you see it?
The metadata, i.due east., the elements and attributes, are fine. So what is wrong? This fourth dimension the problem, again on the first Person line, is in 1 of the values. Someone decided that yes is a practiced plenty substitute for true – but code like below will neglect to get the first chemical element as it is looking for true, not for yes:
Now that you know the types of errors that may occur, information technology is time to show how a schema file helps. The first step is creating a sample data file. The sample can be the smallest instance and incorporate nothing but a unmarried inner chemical element. For the above examples, let's create a sample file like this People.xml :
Now build a PowerShell function below and use it with the sample data to create the .xsd schema.
office New-XmlSchema { [CmdletBinding()] Param ( [Parameter(Mandatory)] [ValidateScript({ Examination-Path -Path $_ })] [ValidatePattern('\.xml')] [string]$XmlExample ) $item = Get-Particular $XmlExample $dir = $particular.Directory $name = $item.Name $baseName = $item.BaseName ## build the schema path by replacing '.xml' with '.xsd' $SchemaPath = "$dir\$baseName.xsd" try { $dataSet = New-Object -TypeName Arrangement.Data.DataSet $dataSet.ReadXml($XmlExample) | Out-Nothing $dataSet.WriteXmlSchema($SchemaPath) ## show the resulted schema file Get-Item $SchemaPath } catch { $err = $_.Exception.Message Write-Host "Failed to create XML schema for $XmlExample`nDetails: $err" -ForegroundColor Crimson } }
Copy the part to your ISE or your favorite Powershell editor, load it into memory and use information technology to create the schema. With the function loaded, the code to create the schema is this one-liner:
New-XmlSchema -XmlExample 'C:\Work\People.xml'
The results will prove the path to the newly created schema:
Using the Schema File to Validate Your Information
Take a wait at the location specified by the results above. If the .xsd is at that place, you lot are on the correct way to see the validation in action. For the confirmation step, use the function below:
Load the function to retentiveness, and apply information technology to validate the MorePeople.xml from the two error examples. To trigger the validation, utilise the control below:
The actual results depend on the content of MorePeople.xml.
Allow's see two examples. Find that when MorePeople.xml is error-free, the function above will return True.
When the MorePeople.xml file contains wrong data (the Land primal misspelled as County), the function will return some failure details and return Faux.
As you can come across, the error specified on the verbose output is very informative: Information technology directs to the culprit file and points to the exact component in information technology where the problem occurred.
Fine Tuning the Validation Schema
Permit's take a look at the schema file, then see how we can make it fifty-fifty better.
The schema created by the New-XmlSchema by default is beneath:
The default schema to a higher place is good, but non perfect. Indeed it has defenseless the typo with the Country attribute. But, if yous leave the schema as-is, in example other expectations y'all might have are not met – these issues will not be reported as errors by the Test-XmlBySchema validation. Let's solve this.
The table beneath presents some cases that are non considered validation errors and volition go unnoticed past Test-XmlBySchema. On each row, the right column shows how to manually alter the schema to add together support for the necessary protection.
A modified version of the schema file, with all protections added, is shown correct after the table.
Adding setting to the default schema – examples
Required Behavior
Relevant setting on the schema file
At to the lowest degree one Person chemical element
Set the minOccurs value of the Person element to i
Brand Name, Country and IsAdmin attributes mandatory
Add employ="required" to each of these attributes annunciation
Allow only true/simulated values for IsAdmin
Fix blazon="xs:boolean" for the IsAdmin declaration
Permit only Country names betwixt3 and 40 characters
Employ the xs:restriction(see detailed explanation after the schema text)
With the boolean restriction in place for the IsAdmin aspect in the example, its value must exist a lower casetruthful or false.
String Length Validation with xs:restriction
The cord length validation is a bit complex. Then, even though it is shown higher up as part of the modified schema, it deserves a picayune more focus.
The original schema particular for the Land attribute (after having manually added the use="required"), is as beneath:
To add the length protection yous should add the <xs:simpleType> element, and inside it, the <xs:restriction base="xs:cord">. This restriction in turn contains the required limits declared on xs:minLength and on xs:minLength.
Post-obit all these changes the final xs:attribute declaration has grown from a unmarried line to a giant 8 lines node:
<xs:attribute name="Land"> <xs:simpleType> <xs:restriction base of operations="xs:string"> <xs:minLength value="3"/> <xs:maxLength value="40"/> </xs:restriction> </xs:simpleType> </xs:attribute>
If your head does not spin later on the explanation above, yous earned the right to meet the validation in action. To practise that let'southward intentionally shorten the value Canada to a two characters syllable: Ca
With the short country name in place, and MorePeople.xml saved, you are ready to run the validation command beneath:
and the results indeed show the complex schema has done its work:
XML schema validation can abound in complexity and validate just about whatsoever blueprint you can call back of, especially when combined with regular expressions.
Related: Getting Started with PowerShell and Regex
0 Response to "Powershell Xml Select Node By Attribute"
Post a Comment