您好我是Powershell的新手,但我已经全神贯注地回答了这个问题,如何在PowerShell中将XML数据转换为CSV数据?
这是我的xml文件:
<users>
<user>
<id>"data"</id>
<name>"data"</name>
<disabled>"data"</disabled>
<title>"data"</title>
<email>"data"</email>
<role>
<name>"data"</name>
</role>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60019</custom_field_id>
<value>"data"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60021</custom_field_id>
<value>"data"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60018</custom_field_id>
<value>"data"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"data"</name>
</site>
</user>
</users>
树中多层的字段是最大的痛苦。这是我到目前为止提出的脚本。我能够获得名称和电子邮件等基本字段。我真的需要标记自定义字段及其子集的字段。
#Converts the xml to a CSV file
$samage_users.users.user | select-Object @(
@{l="Email";e={$_.email}},
@{l="Name";e={$_.name}},
@{l="ID";e={$_.ID}},
@{l="Phone";e={$_.phone}},
@{l="Site";e={$_.site.name}},
@{l="Reports_To";e={$_.reports_to.name}},
@{l="Reports_To_Email";e={$_.reports_to.email}})|
export-csv "Samanage_users.csv" -NoTypeInformation -Append
$page ++
start-sleep -s 10
}
While ($page -lt ($pages + 2))
}
Function NewUsers
{
foreach ($user in $new_user)
{
CSV输出文件应该如下所示。 (见附件)
非常感谢任何帮助!
由于
答案 0 :(得分:2)
您需要生成一个对象,类似于您现在的操作方式,但在输出之前,您需要为每个自定义字段添加属性。如果您的用户具有不同的自定义字段,则唯一的复杂功能就在于此。由于PowerShell不会输出数组中第一个项目的任何属性,因此您必须找到所有可能的属性,并将它们添加到第一个对象。这应该做你想要的我相当肯定。我已经使用不同的自定义字段(用60034替换60019)向XML添加了第二个用户以显示输出。
[xml]$samage_users=@'
<users>
<user>
<id>"data"</id>
<name>"data"</name>
<disabled>"data"</disabled>
<title>"data"</title>
<email>"data"</email>
<role>
<name>"data"</name>
</role>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60019</custom_field_id>
<value>"data"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60021</custom_field_id>
<value>"data"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60018</custom_field_id>
<value>"data"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"data"</name>
</site>
</user>
<user>
<id>"data2"</id>
<name>"data2"</name>
<disabled>"data2"</disabled>
<title>"data2"</title>
<email>"data2"</email>
<role>
<name>"data2"</name>
</role>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60021</custom_field_id>
<value>"data2"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60018</custom_field_id>
<value>"data2"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60034</custom_field_id>
<value>"data2"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"data2"</name>
</site>
</user>
</users>
'@
$Results = ForEach($User in $samage_users.users.user) {
$UserObject = [PSCustomObject][ordered]@{
"Email" = $User.email
"Name" = $User.name
"ID" = $User.ID
"Phone" = $User.phone
"Site" = $User.site.name
"Reports_To" = $User.reports_to.name
"Reports_To_Email" = $User.reports_to.email
}
$User.custom_fields_values.custom_fields_value | ForEach {Add-Member -InputObject $UserObject -NotePropertyName $_.custom_field_id -NotePropertyValue $_.value}
$UserObject
}
$Results | ForEach{ $_.PSObject.Properties.Name }| Select -Unique | Where{ $_ -notin $Results[0].PSObject.Properties.Name } | ForEach{ Add-Member -InputObject $Results[0] -NotePropertyName $_ -NotePropertyValue ' ' }
$Results | FT *
输出是:
Email Name ID Phone Site Reports_To Reports_To_Email 60019 60021 60018 60034
----- ---- -- ----- ---- ---------- ---------------- ----- ----- ----- -----
"data" "data" "data" "data" "data" "data" "data"
"data2" "data2" "data2" "data2" "data2" "data2" "data2"
如果需要输出到文件,您可以轻松地将$Results
传送到Export-Csv
。
答案 1 :(得分:0)
这是我对TheMadTechnician's answer的更改,并附有必要的解释说明:
$RObj = ForEach ($User in $samage_users.users.user) {
### calculate basic properties - even those ones absent in XML
$UObj = $user | Select-Object @(
@{l="Email";e={$_.email}},
@{l="Name";e={$_.name}},
@{l="ID";e={$_.ID}},
@{l="Phone";e={$_.phone}},
@{l="Site";e={$_.site.name}},
@{l="Rs_To";e={$_.reports_to.name}}, # "Rs_To" cut "Reports_To"
@{l="Rs_To_E";e={$_.reports_to.email}} # "Rs_To_E" cut "Reports_To_Email"
# cuttings merely for better output readability
)
### add user-dependent properties for each custom field
$User.custom_fields_values.custom_fields_value |
ForEach-Object {
$UObj | Add-Member NoteProperty -Name $_.custom_field_id -Value $_.value
}
$UObj ### add current PSCustomObject to the `$RObj` array
}
### mutually arrange potentially missing user-dependent properties
for ($i = 0; $i -lt $RObj.Count; $i++ ) {
for ($j = 0; $j -lt $RObj.Count; $j++ ) {
if ( $i -ne $j ) {
$RObj[$i] | ForEach-Object { $_.PSObject.Properties.Name } |
Where-Object { $_ -notin $RObj[$j].PSObject.Properties.Name } |
ForEach-Object {
$RObj[$j] | Add-Member -MemberType NoteProperty -Name $_ -Value ''
}
}
}
}
### $RObj | Export-Csv "Samanage_users.csv" -NoTypeInformation
### debugging output instead of `Export-Csv`
$RObj | Format-Table -Property * -AutoSize
输入(修改后的原始XML
);单独输入以避免在上面的代码中垂直滚动:
$samage_users=[xml]@'
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user>
<id>"dI"</id>
<name>"dN"</name>
<disabled>"dD"</disabled>
<title>"dT"</title>
<email>"dE"</email>
<role>
<name>"dR"</name>
</role>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60044</custom_field_id>
<value>"dC1"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60021</custom_field_id>
<value>"dC2"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60018</custom_field_id>
<value>"dC3"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"dSi"</name>
</site>
</user>
<user>
<id>"d2I"</id>
<name>"d2N"</name>
<disabled>"d2D"</disabled>
<title>"d2T"</title>
<email>"d2E"</email>
<role>
<name>"d2R"</name>
</role>
<Reports_To>
<name>"d2RTn"</name>
<email>"d2RTe"</email>
</Reports_To>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60021</custom_field_id>
<value>"d2C1"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60018</custom_field_id>
<value>"d2C2"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60034</custom_field_id>
<value>"d2C3"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"d2Si"</name>
</site>
</user>
<user>
<id>"d3I"</id>
<name>"d3N"</name>
<disabled>"d3D"</disabled>
<title>"d3T"</title>
<email>"d3E"</email>
<role>
<name>"d3R"</name>
</role>
<custom_fields_values>
<custom_fields_value>
<custom_field_id>60055</custom_field_id>
<value>"d3C1"</value>
</custom_fields_value>
<custom_fields_value>
<custom_field_id>60066</custom_field_id>
<value>"d3C2"</value>
</custom_fields_value>
</custom_fields_values>
<site>
<name>"d3Si"</name>
</site>
</user>
</users>
'@
<强>输出强>:
PS D:\PShell D:\PShell\SO\47660787.ps1
Email Name ID Phone Site Rs_To Rs_To_E 60044 60021 60018 60034 60055 60066
----- ---- -- ----- ---- ----- ------- ----- ----- ----- ----- ----- -----
"dE" "dN" "dI" "dSi" "dC1" "dC2" "dC3"
"d2E" "d2N" "d2I" "d2Si" "d2RTn" "d2RTe" "d2C1" "d2C2" "d2C3"
"d3E" "d3N" "d3I" "d3Si" "d3C1" "d3C2"
注意关于Tomalak's useful comment声明应始终使用XmlDocument
对象的.Load()
方法读取XML文件。< / p>
### $samage_users defined as above i.e. a herestring cast to [xml] type
$xml = New-Object Xml
$xml.Load("Samanage_users.xml") ### a file containing above herestring content
Compare-Object $samage_users.InnerXml $xml.InnerXml ### no difference