Reputation: 29
I would like to export this xml file into Excel (CSV). I have search online for some examples but I cant seem to find anything which can hep me.
I'm not good with powershell.
<?xml version="1.0" encoding="UTF-8"?>
<products updated="12/16/2015">
<product name="office">
<addresslist type="IPv6">
<address>2</address>
<address>256</address>
<address>434</address>
</addresslist>
<addresslist type="IPv4">
<address>13.107</address>
<address>13.14/24</address>
</addresslist>
<addresslist type="URL">
<address>*.google</address>
<address>*.yahoo</address>
<address>*.some other link</address>
</addresslist>
</product>
<product name="LYO">
<addresslist type="URL">
<address>*.rtrt</address>
<address>eever</address>
</addresslist>
<addresslist type="IPv4">
<address>23.178</address>
<address>23.18</address>
<address>23.19</address>
</addresslist>
<addresslist type="IPv6">
<address>2a01:13::/4</address>
<address>2a01:1</address>
</addresslist>
</product>
</products>
This is what I have wrtten but its not giving what I need.
[xml]$file = get-content ./O365IPAddresses.xml
$xmlProperties = $file.SelectNodes("/products/product")
Foreach ($xmlProperty in $xmlProperties) {
$o = New-Object Object
Add-Member -InputObject $o -MemberType NoteProperty -Name Name -Value $xmlProperty.name
foreach ($p in $xmlProperty.addresslist)
{
$type += $p.type
$add += $p.address
}
Add-Member -InputObject $o -MemberType NoteProperty -Name Type -Value $type
Add-Member -InputObject $o -MemberType NoteProperty -Name Address -Value $add
$type="";
$add="";
#Add-Member -InputObject $o -MemberType NoteProperty -Name Name -Value $xmlProperty.name
$o
}
$o="";
This is what i need the code to output.
Name Type V
Office IPv4 12111,12121,12,12,1,2,12,1,2,
Office IPv6 12111,12121,12,12,1,2,12,1,2,
Office URL google, yahoo
lyo IPv4 12111,12121,12,12,1,2,12,1,2,
lyo IPv6 12111,12121,12,12,1,2,12,1,2,
lyo URL some lyn, yahoo
Upvotes: 0
Views: 3116
Reputation: 13537
You were on the right track, but doing the Add-Member stuff will lead you into failure. PowerShell is an object oriented language, so it's much better to just emit and object as you go through a chunk of code, and let PowerShell collect them all for you in the pipeline.
I've amended and truncated your code. With this code:
$xmlProperties = $file.SelectNodes("/products/product")
$o = New-Object Object
Foreach ($xmlProperty in $xmlProperties) {
foreach ($p in $xmlProperty.addresslist)
{
[pscustomobject]@{Name=$xmlProperty.Name;Type=$p.type;Address=$p.address}
}
}
You'll get this output:
Name Type Address
---- ---- -------
office IPv6 {2, 256, 434}
office IPv4 {13.107, 13.14/24}
office URL {*.google, *.yahoo, *.some other link}
LYO URL {*.rtrt, eever}
LYO IPv4 {23.178, 23.18, 23.19}
LYO IPv6 {2a01:13::/4, 2a01:1}
Which you can pipe into Export-Csv
to make into a spreadsheet.
I want to draw attention to the [pscustomobject]
notation. This is a PowerShell v3 and up shorthand for creating a new object, which accepts a key-value pair of object property and values. So, at this point in our for-each loop, we've got the variable $p
defined, which has the following values:
type address
---- -------
IPv6 {2a01:13::/4, 2a01:1}
We're making a new object here, grabbing the .Name
property of the parent object $xmlProperty
, and then picking out the two extra values from $p
we wanted to bring over as well.
Hope this helps.
If one of your properties contains more than one values, then you'll get a weird output in your CSV file. Essentially, PowerShell will scrape through the output, and rerender it in comma separated value format. When a property has two values, PowerShell will list it as System.String[] or the full object name with []
appended at the end, which is notation for an array (object containing more than one item).
$xmlProperties = $file.SelectNodes("/products/product")
$o = New-Object Object
Foreach ($xmlProperty in $xmlProperties) {
foreach ($p in $xmlProperty.addresslist)
{
[pscustomobject]@{Name=$xmlProperty.Name;Type=$p.type;Address=$p.address}
}
} | select Name, Type, @(N={Address};exp={$_.Address -join ','}}
Upvotes: 1