hellen_dorandt89
hellen_dorandt89

Reputation: 457

Importing XML into Powershell as structured data

Looking at the documentation, there are commands for importing and exporting Json and csv data in Powershell. For Xml there only seems to be ConvertTo-Xml. I anticipate working with Xml allot more and it is thus far prooving difficult getting Xml data into powershell sessions.

I tried a number of solutions all using what looks to be .Net or C# calls to import Xml and thus far all have given me errors, I dont know any .Net or C#. For example, this answer suggests to do:

[xml]$xmlObject = (New-Object System.Net.WebClient).DownloadString("Filepath")   

Write-Host $xmlObject.root.User_Blob.Item.Key

I tied the solution using the question askers own Xml:

[xml]$xmlObject = (New-Object System.Net.WebClient).DownloadString("C:temp\Sample 2.xml")
Write-Host $xmlObject.root.User_Blob.Item.Key

I got this error:

MetadataError: Cannot convert value "<?xml version="1.0" encoding="utf-16"?>  
<root>  
<User_Blob>  
<Item>  
<Key>LogonMethod</Key>  
<Value>prompt</Value>  
</Item>  
<Item>  
<Key>ServerURLEntered</Key>  
<Value>http://myserver/config.xml</Value>  
</Item>  
<Item>  
<Key>ServerURLListUsers</Key>  
<Value>  
<LSOption>http://myurl/config.xml</LSOption>  
<LSOption>http://myurl</LSOption>  
</Value>  
</Item>  
<Item>  
<Key>UserDisplayDimensions</Key>  
<Value>fullscreen</Value>  
</Item>  
</User_Blob></root>'" to type "System.Xml.XmlDocument". Error: "The specified node cannot be inserted as the valid child of th  
is node, because the specified node is the wrong type."

I also tried the same answers second solution:

$xmlObject = New-Object XML
$xmlObject.Load("C:temp\Sample 2.xml")

and I could not get to the third line as I got this error before:

MethodInvocationException: Exception calling "Load" with "1" argument(s): "There is no Unicode byte order mark. Cannot switch to  
Unicode."

I followed other solutions on a few powershell blogs and even tried a few xml modules and I've had no success.

To be clear I am simply looking for a way to import something like the sample file below as either a hashtable or a PSObject:

<?xml version="1.0"?>
<results command="list0" result="1">
    <items display_path="C:\Temp" lister="0x20517e0" path="C:\Temp" tab="0x4e2522">
        <item id="20" name="White.png" path="C:\Temp\White.png" sel="0" type="0" />
        <item id="1" name="All Tasks.lnk" path="C:\Temp\All Tasks.lnk" sel="0" type="0" />
        <item id="15" name="Recipes.lnk" path="C:\Temp\Recipes.lnk" sel="1" type="0" />
        <item id="16" name="Dinner plan.lnk" path="C:\Temp\Dinner plan.lnk" sel="1" type="0" />
        <item id="14" name="Car.lnk" path="C:\Temp\Car.lnk" sel="1" type="0" />
        <item id="18" name="bike.lnk" path="C:\Temp\bike.lnk" sel="1" type="0" />
        <item id="5" name="blue.png" path="C:\Temp\blue.png" sel="0" type="0" />
        <item id="4" name="Black.png" path="C:\Temp\Black.png" sel="0" type="0" />
        <item id="7" name="File 2.ahk" path="C:\Temp\File 2.ahk" sel="0" type="0" />
        <item id="9" name="File 4.ahk" path="C:\Temp\File 4.ahk" sel="0" type="0" />
        <item id="6" name="file 1.ahk" path="C:\Temp\file 1.ahk" sel="0" type="0" />
        <item id="8" name="File 3.ahk" path="C:\Temp\File 3.ahk" sel="0" type="0" />
    </items>
</results>

PSVersion 7.3.0-preview.7

Windows Terminal Preview 1.15.2003.0


I have taken the liberty to cross post this question on other forums as well.

Any help would be greatly appreciated!

Upvotes: 0

Views: 808

Answers (1)

Cainan Barbie
Cainan Barbie

Reputation: 56

This works for me, when input directly into the PS console. When loading from a file you may have to account for unexpected encoding, BOM, extraneous characters, etc. Encodings and file formats are a whole chapter by themselves. All of us having encoding pain at some point :)

You probably know already but @"..."@ is a multi-line string literal in PS. Using PS's default string encoding, so it just works :)

$xmlString = @"
<?xml version="1.0"?>
<results command="list0" result="1">
    <items display_path="C:\Temp" lister="0x20517e0" path="C:\Temp" tab="0x4e2522">
        <item id="20" name="White.png" path="C:\Temp\White.png" sel="0" type="0" />
        <item id="1" name="All Tasks.lnk" path="C:\Temp\All Tasks.lnk" sel="0" type="0" />
        <item id="15" name="Recipes.lnk" path="C:\Temp\Recipes.lnk" sel="1" type="0" />
        <item id="16" name="Dinner plan.lnk" path="C:\Temp\Dinner plan.lnk" sel="1" type="0" />
        <item id="14" name="Car.lnk" path="C:\Temp\Car.lnk" sel="1" type="0" />
        <item id="18" name="bike.lnk" path="C:\Temp\bike.lnk" sel="1" type="0" />
        <item id="5" name="blue.png" path="C:\Temp\blue.png" sel="0" type="0" />
        <item id="4" name="Black.png" path="C:\Temp\Black.png" sel="0" type="0" />
        <item id="7" name="File 2.ahk" path="C:\Temp\File 2.ahk" sel="0" type="0" />
        <item id="9" name="File 4.ahk" path="C:\Temp\File 4.ahk" sel="0" type="0" />
        <item id="6" name="file 1.ahk" path="C:\Temp\file 1.ahk" sel="0" type="0" />
        <item id="8" name="File 3.ahk" path="C:\Temp\File 3.ahk" sel="0" type="0" />
    </items>
</results>
"@

$test = [xml]$xmlString
$test.results.items.item | where id -eq 16
# bit of xpath
$test.CreateNavigator().Select("//item[@id=16]").UnderlyingObject

Upvotes: 1

Related Questions