banner



Powershell Xml Select Node By Attribute

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>

            <Computers> 	<Calculator> 		<Proper name>SRV-01</Name> 		<Ip>127.0.0.i</Ip> 		<Include>true</Include> 	</Computer>	 	<Figurer> 		<Name>SRV-02</Name> 		<Ip>192.168.0.102</Ip> 		<Include>simulated</Include> 	</Computer>	 	<Computer> 		<Name>SRV-03</Proper noun> 		<Ip>192.168.0.103</Ip> 		<Include>true</Include> 	</Computer>	 </Computers>          

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.

            Select-Xml -Path C:\Work\computers-elm.xml -XPath '/Computers/Computer/Proper noun' | ForEach-Object { $_.Node.InnerXML }          

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.

            <Computers> 	<Estimator name="SRV-01" ip="127.0.0.1" include="true" /> 	<Figurer name="SRV-02" ip="192.168.0.102" include="false" /> 	<Calculator name="SRV-03" ip="192.168.0.103" include="truthful" /> </Computers>          

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.

            Select-Xml -Path C:\Work\computers-attr.xml -XPath '/Computers/Estimator' | ForEach-Object { $_.Node.name }          

And indeed, this besides brings the same results: SRV-01, SRV-02 and SRV-03 :

Reading data using Select-Xml
Reading data using Select-Xml

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.

            [xml]$xmlElm = Get-Content -Path C:\Work\computers-elm.xml [xml]$xmlAttr = Get-Content -Path C:\Work\computers-attr.xml          

Reading XML Object Elements

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.

            $xmlElm.Computers.Calculator.ip $xmlAttr.Computers.Figurer.ip          

And the results below show that both got the same data, each one from its corresponding file:

PowerShell to Parse XML : Reading XML Attributes
PowerShell to Parse XML : Reading XML Attributes

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.

IntelliSense and tab completion for XML object
IntelliSense and tab completion for XML object

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:

Connection status results
Connectedness condition results

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?

            <People> 	<Person Proper noun="Debra" Canton="Canada" IsAdmin="true" /> 	<Person Name="Jacob" State="Israel" IsAdmin="truthful" /> 	<Person Name="Olivia" Country="Republic of cyprus" IsAdmin="simulated" /> </People>          

Exercise not worry if you didn't, it is just hiding. The problem is found in the outset inner element:

What should take been a Country was misspelled, and Canada was degraded to a County.

Errors in the XML Information

After fixing the Country effect on MorePeople.xml, some other trouble sneaked in:

            <People> 	<Person Name="Debra" Country="Canada" IsAdmin="yeah" /> 	<Person Name="Jacob" Country="Israel" IsAdmin="true" /> 	<Person Name="Olivia" Country="Cyprus" IsAdmin="fake" /> </People>          

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:

            $peopleXml.People.Person | Where-Object IsAdmin -eq 'true'          

Creating an XML Schema

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 :

            <People> 	<Person Name="Jeff" Country="Us" IsAdmin="truthful" /> </People>          

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:

Creating XML schema from a sample data file
Creating XML schema from a sample data file

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:

            function Test-XmlBySchema {     [CmdletBinding()]     [OutputType([bool])]     param     (         [Parameter(Mandatory)]         [ValidateScript({ Examination-Path -Path $_ })]         [ValidatePattern('\.xml')]         [string]$XmlFile,         [Parameter(Mandatory)]         [ValidateScript({ Test-Path -Path $_ })]         [ValidatePattern('\.xsd')]         [string]$SchemaPath     )      endeavor     {         [xml]$xml = Become-Content $XmlFile         $xml.Schemas.Add('', $SchemaPath) | Out-Goose egg         $xml.Validate($null)         Write-Verbose "Successfully validated $XmlFile confronting schema ($SchemaPath)"         $result = $true     }     catch     {         $err = $_.Exception.Message         Write-Verbose "Failed to validate $XmlFile against schema ($SchemaPath)`nDetails: $err"         $result = $false     }     finally     {         $outcome     } }          

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:

            Test-XmlBySchema -XmlFile 'C:\Work\MorePeople.xml' -SchemaPath 'C:\Work\People.xsd' -Verbose          

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.

Validation success
Validation success

When the MorePeople.xml file contains wrong data (the Land primal misspelled as County), the function will return some failure details and return Faux.

Validation failure - wrong attribute name detected
Validation failure – wrong attribute name detected

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:

            <?xml version="ane.0" standalone="yes"?> <xs:schema id="People" xmlns="" xmlns:xs="<http://www.w3.org/2001/XMLSchema>" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">   <xs:element name="People" msdata:IsDataSet="true" msdata:UseCurrentLocale="truthful">     <xs:complexType>       <xs:pick minOccurs="0" maxOccurs="unbounded">         <xs:element proper name="Person">           <xs:complexType>             <xs:attribute name="Name" blazon="xs:string" />             <xs:attribute name="Country" blazon="xs:string" />             <xs:attribute name="IsAdmin" type="xs:string" />           </xs:complexType>         </xs:element>       </xs:choice>     </xs:complexType>   </xs:element> </xs:schema>                      

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 betwixt 3 and 40 characters Employ the xs:restriction (see detailed explanation after the schema text)
            <?xml version="one.0" standalone="yep"?> <xs:schema id="People" xmlns="" xmlns:xs="<http://www.w3.org/2001/XMLSchema>" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">   <xs:element name="People" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">     <xs:complexType>       <xs:pick minOccurs="0" maxOccurs="unbounded">         <xs:element name="Person">           <xs:complexType>             <xs:attribute name="Proper noun" type="xs:string" use="required" /> 	    <xs:attribute name="State" employ="required"> 	      <xs:simpleType> 		<xs:restriction base of operations="xs:string"> 		  <xs:minLength value="3"/> 		  <xs:maxLength value="twoscore"/> 		</xs:brake> 	      </xs:simpleType> 	    </xs:attribute>	             <xs:attribute name="IsAdmin" type="xs:boolean" use="required" />           </xs:complexType>         </xs:element>       </xs:option>     </xs:complexType>   </xs:element> </xs:schema>                      

With the boolean restriction in place for the IsAdmin aspect in the example, its value must exist a lower case truthful 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:

            <xs:attribute name="Land" blazon="xs:string" use="required" />          

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:

            Examination-XmlBySchema -XmlFile 'C:\Work\MorePeople.xml' -SchemaPath 'C:\Work\People.xsd' -Verbose          

and the results indeed show the complex schema has done its work:

A string length error detected by the schema validation
A string length error detected past the schema validation

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

Powershell Xml Select Node By Attribute,

Source: https://adamtheautomator.com/powershell-parse-xml/

Posted by: wilcoxsaidecalown.blogspot.com

0 Response to "Powershell Xml Select Node By Attribute"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel