2017-12-05 73 views
0

こんにちは私はPowershellを初めてお使いになりましたが、この質問に対する回答を全部見てきましたが、XMLデータをPowerShellのCSVデータに変換するにはどうすればよいですか?Powerシェルでxmlをcsvに変換する

<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> 

ツリーに複数の層であるフィールドが最大の痛みです:

は、ここに私のxmlファイルです。ここに私がこれまで出てきたスクリプトがあります。私は名前や電子メールのような基本的なフィールドを得ることができます。カスタムフィールドとそのサブセットという名前のフィールドが本当に必要です。

#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出力ファイルは次のようになります。

CSV Output File

(添付参照)すべてのヘルプは大歓迎です!

おかげ

+0

希望の出力も表示します。 – Tomalak

+0

私は自分の投稿に訂正しました。 –

+0

本当ですか?適切な値を持つ '60019'という名前の列だけでなく、それぞれに「CUSTOM FIELD ID」と「CUSTOM FIELD VALUE」が必要ですか? – TheMadTechnician

答えて

0

ここTheMadTechnician's answerの私の変更が必要な説明のコメントで、です:(オリジナルXMLを修正)

$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 

入力。上記のコードでは、垂直スクロールを避けるために、別々に入力:

$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の点でXMLファイルは常にXmlDocumentオブジェクトの.Load()メソッドを使用して読まれるべきであることをを述べます

###     $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 
2

あなたは同様にあなたは今それをやっている方法に、オブジェクトを生成する必要があるだろうが、あなたはそれを出力する前に、各カスタムフィールドのためにそれにプロパティを追加する必要があります。異なるカスタムフィールドを持つユーザーがいる場合は、唯一の問題が発生します。 PowerShellは、配列の最初の項目が持つすべてのプロパティを出力しないため、潜在的なすべてのプロパティを見つけて最初のオブジェクトに追加する必要があります。これはあなたが望むことを行うはずです。私はかなり確信しています。私は出力を表示するために、別のカスタムフィールド(60019を60034に置き換えて)を使って2番目のユーザーをXMLに追加しました。

[xml][email protected]' 
<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" 

あなたはそれをファイルに出力Export-Csvに同じように簡単にパイプ$Resultsを必要とすることができれば。

+0

XMLファイルは常に 'XmlDocument'オブジェクトの' .Load() 'メソッド(' Get-Content'と明示的な '[xml]'キャストとは対照的に)を使って読み込まなければならないことは注目に値します。 。 – Tomalak

+0

Add-Member:パラメータ 'NotePropertyName'の引数を検証できません。引数がnullまたは空です。 nullまたは空でない 引数を指定してから、コマンドを再試行してください。 Cで :\ Users \ユーザーdyl201 \デスクトップ\ uploadusers.ps1:50文字:117 + ... -InputObject $ユーザーオブジェクト-NotePropertyName $ _ custom_field_id -NotePr ... + ~~~~~~~~~ ~~~~~~~~~ + CategoryInfo:InvalidData:(:) [アドオンメンバー]、ParameterBindingValidationException + FullyQualifiedErrorId:ParameterArgumentValidationError、Microsoft.PowerShell.Commands.AddMemberCommand –

+0

私は私を交換したときに私が得たエラーでした$結果から始まるすべてのスクリプトの一部。 コマンドレットコマンドパイプラインの位置1でのエクスポート-Csv 次のパラメータの値を入力してください: InputObject: –