Return to site

Download Powershell Convert Xml Document To Stringbackstage

broken image


PowerShell has awesome XML support. It is not obvious at first, but with a little help from your friends here at PowerShellMagazine.com, you'll soon solve every-day XML tasks – even pretty complex ones – in no time.

ConvertTo-Xml returns an in-memory representation of an XML document, so you can continue to process it in PowerShell. ConvertTo-Xml does not have an option to convert objects to CLI XML. Examples Example 1: Convert a date to XML PS C: Get-Date ConvertTo-Xml. This command converts the current date (a DateTime object) to XML. The Select-Xml cmdlet lets you use XPath queries to search for text in XML strings and documents. Enter an XPath query, and use the Content, Path, or Xml parameter to specify the XML to be searched.

So let's check out how you put very simple PowerShell code to work to get the things done that used to be so mind-blowingly complex in the pre-PowerShell era.

Let's create an XML document from scratch, add new data sets, change pieces of information, add new data, remove data, and save an updated version of it to a new well-formed XML file.

Creating New XML Documents

Creating completely fresh XML documents from scratch used to be a tedious task. Many scripters resorted to creating XML files as a plain text. While that's OK, it is error prone. Chances are that typos and case issues sneak in, and you may find yourself in an unfriendly world of malformed and dysfunctional XML.

No more, because there's a buddy that can help you create XML documents: the XMLTextWriter object. It shields the complexity of dealing with the raw XML object model, and instead assists you in writing your pieces of information to an XML file.

To begin this story, let's create a fairly complex XML document that the upcoming examples can use to play with. The goal is to create an XML document that has all the typical things in it: nodes, attributes, data sections, and comments.

This script generates a fake server inventory with a lot of random information. The result is opened in notepad and will look similar to this:

The purpose of this XML document is two-fold: it serves as an example how you can create XML files from scratch, and it serves as sample data for the following exercises.

Just assume this was an XML file with relevant information. You can apply the tactics you are about to learn to any well-formed XML file.

Attention: XMLTextWriter does a lot of magic for you, but you are responsible for creating meaningful content. One of the issues that can easily burn your feet is a malformed node name. Node names must not contain spaces.

So while 'CodeSegment' is OK, 'Code Segment' would not be OK. XML would try and name your node 'Code', then add an attribute named 'Segment', and finally choke on the fact that you never assigned a value to the attribute.

Finding Information in XML Files

One common task is to extract information from an XML file. Let's assume you need a list of machines and their IP addresses. Provided you have generated the sample XML file above, then this is all it takes to create the report:

The result will look similar to this:

Note: Some of you may wonder why I used an XML object in the first place. Often you find code like this:

The simple reason is performance. Reading in the XML file as a plain text file via Get-Content and then casting it to XML in a second step is a very expensive approach. Even though our XML file isn't that large, the latter solution takes almost 7 times more time than the first one, and this will add up with even larger XML files.

So whenever you want to load an XML file, make sure you get an XML object and use its Load() method. This method is versatile enought by the way to also accept URLs, so you can use an URL to your favorite RSS feed as well – provided you have direct Internet access and no proxy settings to configure.

Picking Particular Instances

Let's assume you do not want a list of all servers, but instead just want to look up the IP address and the information attribute info1 for a specific server in your list. You could use the same approach like this:

This would get you the IP address for 'server0009' plus the info1 attribute. Instead of querying all elements and then picking the one you are after on the client side, you can also use XPath, a XML query language:

The XPath query '//Machine[Name='Server0009″]' looks for all 'Machine' nodes that have a sub-node called 'Name' with a value of 'Server0009'.

Important: XPath is case-sensitive, so if the node name is 'Machine', then you cannot query for 'machine'.

As a side note, in both approaches you need a script block to access attributes because the attribute 'info1' is part of a sub-node 'Information'. As always in these scenarios, you can use a hash table to assign a better name to that piece of information:

The result will look similar to this:

Iges to stl converter online. XPath is an extremely powerful XML query language. You can find information on its syntax all over the place in the Internet (check these links for example: http://www.w3schools.com/xpath/ and http://go.microsoft.com/fwlink/?LinkId=143609). When you read these documents, you will find that XPath can also use so-called 'user-defined functions' like last() or lowercase(). These functions are not supported here.

Changing XML Content

Often, you will want to update information in an XML document. Rather than parsing the XML yourself, simply stick to the techniques you just learned.

So if you wanted to update Server0006 and assign it a new name and a different IP address, this is what you would do:

Xml

As you can see, updating information is simple, and all changes you make are applied automatically to the underlying XML object. All you need to do is to save the changed XML object to file to make your changes permanent. The result is displayed in the Notepad editor and will look similar to this:

You have just made changes to an existing XML document in no time, without tricky parsing, and without risking to break XML structure.

In the same way, you can make bulk adjustments. Let's assume all the servers are to get brand new names. Instead of 'ServerXXXX', the machines now need to be named like 'Prod_ServerXXXX'. Here's the solution:

Note how all server names in the XML document have been updated. Select-XML this time won't return just one object but many, one for each server. This is because XPath this time selects all 'Machine' nodes without special filtering. That's why all of these nodes need to be processed in a foreach loop.

Inside of the loop, the node 'Name' is assigned a new value, and once all 'Machine' nodes are updated, the XML document is saved and opened in Notepad.

You may argue that in this example, prepending the server name with 'Prod_' is really a trivial change, and that is true. There may be more complex requirements. However, the focus here is to show how you fundamentally change XML data, not how you do sophisticated string operations.

Still, if you ask yourself how you would, for example, replace 'ServerXXXX' with 'PCXX' (including turning a 4-digit number into a 2-digit number, so this definitely is not a trivial change), here is a solution as well:

This time, a regular expression extracts the numeric part of the original server name, then the -f operator reformats the number and adds it to the new server prefix.

Neither regular expressions nor number formatting are in the focus of this article. The important part is to see that you are free to use whatever technique you like to construct the new server name. At the end of the day, changing the XML content always sticks to the same rules, though.

Adding New Data

Occasionally, updating data is not enough. You may want to add a new computer to the list. Again, this is straightforward. You simply pick an existing node, clone it, then update its content and append it to the parent of your liking. This way, you do not have to create the complex node structure yourself and can be certain that the new node is structured just like any of the existing nodes.

This will add a new machine to the list of machines:

Since the node you are adding is cloned from an existing node, all information in this new node is copied from the existing node. Information that you do not update will keep the old values.

And what if you wanted to add the new node to the top of the list? Simply use InsertBefore() instead of AppendChild():

Likewise, you can basically insert the new node anywhere. This would insert it right after Server0007:

Removing XML Content

Deleting data entirely from your XML file is just as easy. If you wanted to remove Server0007 from your list, here's how:

Enormous Power at Your Fingertips

With the examples presented, you can now manage the most commonly needed XML manipulations in just a couple of lines of code. It is well worth investing some time into improving your XML and XPath proficiency – you can do amazing things with them.

And for those of you that have sticked with me this long, I have a little present for you: a great little tool I use very often that can be very helpful for you, too, I am sure. It uses the exact same tactics you just heard about. Here's the story:

ConvertTo-XML can convert any object into XML, and since XML is a hierarchical data format, preserving structure up to a given depth, it is an excellent way of examining nested object properties. So you can 'unfold' an object structure and look at all of its properties, even the deeply nested ones.

Without XML and XPath, all you could do is look at plain XML and search for information yourself. For example, if you wanted to find out where exactly the $host object stores PowerShell's color information, you could do this (which might be not such a good idea after all because you get flooded with raw XML information):

Powershell Convert Xml To Object

With the knowledge just presented, you could now take the raw XML and extract and filter the object properties.

So here's the promised function called Get-ObjectProperty which works a little bit like Get-Member on steroids. It can tell you which property inside an object holds the value you are after. Have a look:

This will return all nested properties inside of $host that have 'Color' in its name. Console output most likely is truncated, so you are better off displaying the information in a grid view window:

Note the column 'Path': this property specifies exactly how you would access a given nested property. In the example, Get-ObjectProperty walks two levels deep inside the object hierarchy. Greater depths will unfold even more information but will also pollute the results with more irrelevant noise information.

While you can pipe in multiple objects, it is best to pipe only one object due to the large amount of resulting data. This line would list all nested properties in a process object, five levels deep, that have a numeric value:

And this line would return all nested properties of the spooler service object that is of type 'String':

And here's the source code for Get-ObjectProperty. It is slightly more complex than just a couple of lines but still amazingly short, given the job it does for you.

It utilizes the exact same techniques that were just explained, so once you feel comfortable with the simple examples above, you can try and digest this one as well – or simply use it as a tool and not worry about its XML magic:

-->

Syntax

Description

The Select-Xml cmdlet lets you use XPath queries to search for text in XML strings and documents.Enter an XPath query, and use the Content, Path, or Xml parameter to specify the XML to be searched.

Download Powershell Convert Xml Document To Stringbackstage

Examples

Example 1: Select AliasProperty nodes

This example gets the alias properties in the Types.ps1xml.(For information about this file, see about_Types.ps1xml.)

Powershell String To Xml

The first command saves the path to the Types.ps1xml file in the $Path variable.

The second command saves the XML path to the AliasProperty node in the $XPath variable.

The third command uses the Select-Xml cmdlet to get the AliasProperty nodes that are identified by the XPath statement from the Types.ps1xml file.The command uses a pipeline operator to send the AliasProperty nodes to the Select-Object cmdlet.The ExpandProperty parameter expands the Node object and returns its Name and ReferencedMemberName properties.

The result shows the Name and ReferencedMemberName of each alias property in the Types.ps1xml file.For example, there is a Count property that is an alias of the Length property.

Example 2: Input an XML document

C# convert xml to string

As you can see, updating information is simple, and all changes you make are applied automatically to the underlying XML object. All you need to do is to save the changed XML object to file to make your changes permanent. The result is displayed in the Notepad editor and will look similar to this:

You have just made changes to an existing XML document in no time, without tricky parsing, and without risking to break XML structure.

In the same way, you can make bulk adjustments. Let's assume all the servers are to get brand new names. Instead of 'ServerXXXX', the machines now need to be named like 'Prod_ServerXXXX'. Here's the solution:

Note how all server names in the XML document have been updated. Select-XML this time won't return just one object but many, one for each server. This is because XPath this time selects all 'Machine' nodes without special filtering. That's why all of these nodes need to be processed in a foreach loop.

Inside of the loop, the node 'Name' is assigned a new value, and once all 'Machine' nodes are updated, the XML document is saved and opened in Notepad.

You may argue that in this example, prepending the server name with 'Prod_' is really a trivial change, and that is true. There may be more complex requirements. However, the focus here is to show how you fundamentally change XML data, not how you do sophisticated string operations.

Still, if you ask yourself how you would, for example, replace 'ServerXXXX' with 'PCXX' (including turning a 4-digit number into a 2-digit number, so this definitely is not a trivial change), here is a solution as well:

This time, a regular expression extracts the numeric part of the original server name, then the -f operator reformats the number and adds it to the new server prefix.

Neither regular expressions nor number formatting are in the focus of this article. The important part is to see that you are free to use whatever technique you like to construct the new server name. At the end of the day, changing the XML content always sticks to the same rules, though.

Adding New Data

Occasionally, updating data is not enough. You may want to add a new computer to the list. Again, this is straightforward. You simply pick an existing node, clone it, then update its content and append it to the parent of your liking. This way, you do not have to create the complex node structure yourself and can be certain that the new node is structured just like any of the existing nodes.

This will add a new machine to the list of machines:

Since the node you are adding is cloned from an existing node, all information in this new node is copied from the existing node. Information that you do not update will keep the old values.

And what if you wanted to add the new node to the top of the list? Simply use InsertBefore() instead of AppendChild():

Likewise, you can basically insert the new node anywhere. This would insert it right after Server0007:

Removing XML Content

Deleting data entirely from your XML file is just as easy. If you wanted to remove Server0007 from your list, here's how:

Enormous Power at Your Fingertips

With the examples presented, you can now manage the most commonly needed XML manipulations in just a couple of lines of code. It is well worth investing some time into improving your XML and XPath proficiency – you can do amazing things with them.

And for those of you that have sticked with me this long, I have a little present for you: a great little tool I use very often that can be very helpful for you, too, I am sure. It uses the exact same tactics you just heard about. Here's the story:

ConvertTo-XML can convert any object into XML, and since XML is a hierarchical data format, preserving structure up to a given depth, it is an excellent way of examining nested object properties. So you can 'unfold' an object structure and look at all of its properties, even the deeply nested ones.

Without XML and XPath, all you could do is look at plain XML and search for information yourself. For example, if you wanted to find out where exactly the $host object stores PowerShell's color information, you could do this (which might be not such a good idea after all because you get flooded with raw XML information):

Powershell Convert Xml To Object

With the knowledge just presented, you could now take the raw XML and extract and filter the object properties.

So here's the promised function called Get-ObjectProperty which works a little bit like Get-Member on steroids. It can tell you which property inside an object holds the value you are after. Have a look:

This will return all nested properties inside of $host that have 'Color' in its name. Console output most likely is truncated, so you are better off displaying the information in a grid view window:

Note the column 'Path': this property specifies exactly how you would access a given nested property. In the example, Get-ObjectProperty walks two levels deep inside the object hierarchy. Greater depths will unfold even more information but will also pollute the results with more irrelevant noise information.

While you can pipe in multiple objects, it is best to pipe only one object due to the large amount of resulting data. This line would list all nested properties in a process object, five levels deep, that have a numeric value:

And this line would return all nested properties of the spooler service object that is of type 'String':

And here's the source code for Get-ObjectProperty. It is slightly more complex than just a couple of lines but still amazingly short, given the job it does for you.

It utilizes the exact same techniques that were just explained, so once you feel comfortable with the simple examples above, you can try and digest this one as well – or simply use it as a tool and not worry about its XML magic:

-->

Syntax

Description

The Select-Xml cmdlet lets you use XPath queries to search for text in XML strings and documents.Enter an XPath query, and use the Content, Path, or Xml parameter to specify the XML to be searched.

Examples

Example 1: Select AliasProperty nodes

This example gets the alias properties in the Types.ps1xml.(For information about this file, see about_Types.ps1xml.)

Powershell String To Xml

The first command saves the path to the Types.ps1xml file in the $Path variable.

The second command saves the XML path to the AliasProperty node in the $XPath variable.

The third command uses the Select-Xml cmdlet to get the AliasProperty nodes that are identified by the XPath statement from the Types.ps1xml file.The command uses a pipeline operator to send the AliasProperty nodes to the Select-Object cmdlet.The ExpandProperty parameter expands the Node object and returns its Name and ReferencedMemberName properties.

The result shows the Name and ReferencedMemberName of each alias property in the Types.ps1xml file.For example, there is a Count property that is an alias of the Length property.

Example 2: Input an XML document

This example shows how to use the XML parameter to provide an XML document to the Select-Xml cmdlet.

The first command uses the Get-Content cmdlet to get the content of the Types.ps1xml file and save it in the $Types variable.The [xml] casts the variable as an XML object.

The second command uses the Select-Xml cmdlet to get the MethodName nodes in the Types.ps1xml file.The command uses the Xml parameter to specify the XML content in the $Types variable and the XPath parameter to specify the path to the MethodName node.

Example 3: Search PowerShell Help files

This example shows how to use the Select-Xml cmdlet to search the PowerShell XML-based cmdlet help files.In this example, we'll search for the cmdlet name that serves as a title for each help file and the path to the help file.

The first command creates a hash table that represents the XML namespace that is used for the help files and saves it in the $Namespace variable.

Example 4: Different ways to input XML

This example shows two different ways to send XML to the Select-Xml cmdlet.

The first command saves a here-string that contains XML in the $Xml variable.(For more information about here-strings, see about_Quoting_Rules.)

Example 5: Use the default xmlns namespace

This example shows how to use the Select-Xml cmdlet with XML documents that use the default xmlns namespace.The example gets the titles of Windows PowerShell ISE user-created snippet files.For information about snippets, see New-IseSnippet.

The first command creates a hash table for the default namespace that snippet XML files use and assigns it to the $SnippetNamespace variable.The hash table value is the XMLNS schema URI in the snippet XML.The hash table key name, snip, is arbitrary.You can use any name that is not reserved, but you cannot use xmlns.

Convert To Xml Powershell Examples

Parameters

-Content

Specifies a string that contains the XML to search.You can also pipe strings to Select-Xml.

Type:String[]
Position:Named
Default value:None
Accept pipeline input:True
Accept wildcard characters:False

Specifies the paths and file names of the XML files to search.Unlike Path, the value of the LiteralPath parameter is used exactly as it is typed.No characters are interpreted as wildcards.If the path includes escape characters, enclose it in single quotation marks.Single quotation marks tell PowerShell not to interpret any characters as escape sequences.

Type:String[]
Aliases:PSPath, LP
Position:Named
Default value:None
Accept pipeline input:True
Accept wildcard characters:False

Specifies a hash table of the namespaces used in the XML.Use the format @{ = }.

When the XML uses the default namespace, which begins with xmlns, use an arbitrary key for the namespace name.You cannot use xmlns.In the XPath statement, prefix each node name with the namespace name and a colon, such as //namespaceName:Node.

Type:Hashtable
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

Specifies the path and file names of the XML files to search.Wildcard characters are permitted.

Type:String[]
Position:1
Default value:None
Accept pipeline input:True
Accept wildcard characters:True

Specifies one or more XML nodes.

An XML document will be processed as a collection of XML nodes.If you pipe an XML document to Select-Xml, each document node will be searched separately as it comes through the pipeline.

Type:XmlNode[]
Aliases:Node
Position:1
Default value:None
Accept pipeline input:True
Accept wildcard characters:False

Specifies an XPath search query.The query language is case-sensitive.This parameter is required.

Powershell Convert Text To Xml

Type:String
Position:0
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

Inputs

System.String or System.Xml.XmlNode

You can pipe a path or XML node to this cmdlet.

Powershell Xml String To Object

Outputs

Notes

XPath is a standard language that is designed to identify parts of an XML document. For moreinformation about the XPath language, seeXPath Reference and the SelectionFilters section of Event Selection.

Related Links





broken image