次のコードを使用して、XMLをCSVに変換できました。
#read from file
[xml]$inputFile = Get-Content "c:\pstest\test.xml"
#export xml as csv
$inputFile.Transaction.ChildNodes | Export-Csv "c:\pstest\test.csv" -NoTypeInformation -Delimiter:";" -Encoding:UTF8
これは、ファイルに1つのタイプの子ノードを持つ1つのルートノードのみが含まれている場合に機能します。次に例を示します。
<?xml version="1.0" encoding="UTF-8"?>
<Transaction>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>1</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515552017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>2</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515622017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>3</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515972017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
</Transaction>
出力は次のようになります。
"RecordID";"SequenceNumber";"TransactionType";"ActionCode";"TransactionID";"SellerCode";"BuyerCode";"TransactionReference";"TransactionDescription1";"TransactionDescription2";"DocumentType";"DocumentNumber";"DocumentDate";"DocumentAmount";"CurrencyCode";"TransactionAmount";"TransactionDueDate";"AdditionalInformation1";"AdditionalInformation2";"HashCode"
"02";"1";"01";"01";"17500515552017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
"02";"2";"01";"01";"17500515622017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
"02";"3";"01";"01";"17500515972017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
それは素晴らしいです。
ただし、実際の入力ファイルには「ヘッダー行」情報、TXNHEADタグがあります。
<?xml version="1.0" encoding="UTF-8"?>
<Transaction>
<TXNHEAD>
<RecordID>01</RecordID>
<FileName>001</FileName>
<IntermediaryCode>19000033</IntermediaryCode>
<ActualizationDate>20170314</ActualizationDate>
<SequenceNumber>001</SequenceNumber>
<NumberofRecords>3</NumberofRecords>
<AmountofRecords>30000</AmountofRecords>
</TXNHEAD>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>1</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515552017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>2</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515622017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
<TXNDETAIL>
<RecordID>02</RecordID>
<SequenceNumber>3</SequenceNumber>
<TransactionType>01</TransactionType>
<ActionCode>01</ActionCode>
<TransactionID>17500515972017001</TransactionID>
<SellerCode>2200919TRY</SellerCode>
<BuyerCode>KOCZER</BuyerCode>
<TransactionReference> </TransactionReference>
<TransactionDescription1> </TransactionDescription1>
<TransactionDescription2> </TransactionDescription2>
<DocumentType>01</DocumentType>
<DocumentNumber>XXXXXXXXXXX</DocumentNumber>
<DocumentDate>20170301</DocumentDate>
<DocumentAmount>10000</DocumentAmount>
<CurrencyCode>949</CurrencyCode>
<TransactionAmount>10000</TransactionAmount>
<TransactionDueDate>20170505</TransactionDueDate>
<AdditionalInformation1> </AdditionalInformation1>
<AdditionalInformation2> </AdditionalInformation2>
<HashCode>XXXXXXXX</HashCode>
</TXNDETAIL>
</Transaction>
同じコードを適用すると、次のようになります。
"RecordID";"FileName";"IntermediaryCode";"ActualizationDate";"SequenceNumber";"NumberofRecords";"AmountofRecords"
"01";"001";"19000033";"20170314";"001";"3";"30000"
"02";;;;"1";;
"02";;;;"2";;
"02";;;;"3";;
代わりにこのコードを試して、頭だけを取得すると:
#read from file
[xml]$inputFile = Get-Content "c:\pstest\test.xml"
#export xml as csv
$inputFile.Transaction.TXNHEAD.ChildNodes | Export-Csv "c:\pstest\test.csv" -NoTypeInformation -Delimiter:";" -Encoding:UTF8
私は得ます:
"#text"
"01"
"001"
"19000033"
"20170314"
"001"
"3"
"30000"
私が達成しようとしているのは、この出力です:
"RecordID";"FileName";"IntermediaryCode";"ActualizationDate";"SequenceNumber";"NumberofRecords";"AmountofRecords"
"01";"001";"19000033";"20170314";"001";"3";"30000"
"RecordID";"SequenceNumber";"TransactionType";"ActionCode";"TransactionID";"SellerCode";"BuyerCode";"TransactionReference";"TransactionDescription1";"TransactionDescription2";"DocumentType";"DocumentNumber";"DocumentDate";"DocumentAmount";"CurrencyCode";"TransactionAmount";"TransactionDueDate";"AdditionalInformation1";"AdditionalInformation2";"HashCode"
"02";"1";"01";"01";"17500515552017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
"02";"2";"01";"01";"17500515622017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
"02";"3";"01";"01";"17500515972017001";"2200919TRY";"KOCZER";"";"";"";"01";"XXXXXXXXXXX";"20170301";"10000";"949";"10000";"20170505";"";"";"XXXXXXXX"
何が悪いのですか?
最初のオブジェクト(またはSelect-Object
など)は、パイプラインで、ファイルまたはコンソール出力に関係なく、出力のヘッダーを定義します。
あなたができることは、それらを2ラウンドでcsvに変換し、同じファイルに追加することです。例:
$inputFile.Transaction.TXNHEAD | ConvertTo-Csv -NoTypeInformation -Delimiter ";" | Set-Content -Path "c:\pstest\test.csv" -Encoding UTF8
$inputFile.Transaction.TXNDETAIL | ConvertTo-Csv -NoTypeInformation -Delimiter ";" | Add-Content -Path "c:\pstest\test.csv" -Encoding UTF8
次のように組み合わせることもできます。
$inputFile.Transaction.TXNHEAD, $x.Transaction.TXNDETAIL |
ForEach-Object { $_ | ConvertTo-Csv -NoTypeInformation -Delimiter ";" } |
Set-Content -Path "c:\pstest\test.csv" -Encoding UTF8
これが私のコードです:
# =============================================================================
#
# NAME:xml2csv.ps1
#
# AUTHOR:
# THANKS TO: Rick Sheeley (original snippet on STack Overflow)
# DATE :
#
# COMMENT:
# Send large XML with multiple children and Attributes to CSv for analysis
#
# Note: For versions 3.0 or newer only
# =============================================================================
function Get-Attributes([Object]$pnode)
{
if($pnode.HasAttributes) {
foreach($attr in $pnode.Attributes) {
$xattString+= $attr.Name + ":" + $attr."#text" + ","
}
}
else {
$xattString = $pnode.nNode + ": No Attributes,"
}
return $xattString
}
function Get-XmlNode([ xml ]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
{
# If a Namespace URI was not given, use the Xml document's default namespace.
if ([string]::IsNullOrEmpty($NamespaceURI)) { $NamespaceURI = $XmlDocument.DocumentElement.NamespaceURI }
# In order for SelectSingleNode() to actually work, we need to use the fully qualified node path along with an Xml Namespace Manager, so set them up.
$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
$xmlNsManager.AddNamespace("ns", $NamespaceURI)
$fullyQualifiedNodePath = "/ns:$($NodePath.Replace($($NodeSeparatorCharacter), '/ns:'))"
# Try and get the node, then return it. Returns $null if the node was not found.
$node = $XmlDocument.SelectSingleNode($fullyQualifiedNodePath, $xmlNsManager)
return $node
}
cls
$fin = "<Filepath>\<myFile>.xml"
$fout = "<Filepath>\<myFile>.csv"
Remove-Item $fout -ErrorAction SilentlyContinue
[xml]$xmlContent = get-content $fin
$row=0
$COMMA=","
$pNode = "ROOT"
# Replace all "MyTopNode" with your top node...
$nNode = "MyTopNode"
$xmlArray = @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $nNode
$xmlArray[$row].Attribute = ""
$xmlArray[$row].ItemType = "Root"
$xmlArray[$row].Value = $attr."#text"
$row++
if($xmlContent.MyTopNode.HasAttributes) {
foreach($attr in $xmlContent.MyTopNode.Attributes) {
$xmlArray += @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $nNode
$xmlArray[$row].Attribute = $attr.LocalName
$xmlArray[$row].ItemType = "Attribute"
$xmlArray[$row].Value = $attr."#text"
$row++
}
}
# Begin TRY
try {
foreach($node in $xmlContent.MyTopNode.ChildNodes) {
$pNode = "MyTopNode"
$nNode = $node.LocalName
$xmlArray += @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $nNode
$xmlArray[$row].Attribute = ""
$xmlArray[$row].ItemType = "Root"
$xmlArray[$row].Value = $attr."#text"
$row++
if($nNode.HasAttributes) {
foreach($attr in $node.Attributes) {
$xmlArray += @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $nNode
$xmlArray[$row].Attribute = $attr.LocalName
$xmlArray[$row].ItemType = "Attribute"
$xmlArray[$row].Value = $attr."#text"
$row++
}
}
foreach($sNode in $node.ChildNodes) {
$pNode = $nNode
$snNode = $sNode.LocalName
$xmlArray += @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $snNode
$xmlArray[$row].Attribute = ""
$xmlArray[$row].ItemType = "Root"
$xmlArray[$row].Value = $attr."#text"
$row++
if($sNode.HasAttributes) {
foreach($attr in $sNode.Attributes) {
$xmlArray += @(
[pscustomobject]@{Row= $row;Parent=$pNode;Node=$nNode;Attribute='';ItemType='Root';Value=''})
$xmlArray[$row].Row = $row
$xmlArray[$row].Parent = $pNode
$xmlArray[$row].Node = $snNode
$xmlArray[$row].Attribute = $attr.LocalName
$xmlArray[$row].ItemType = "Attribute"
$xmlArray[$row].Value = $attr."#text"
$row++
}
}
}
}
$xmlArray | SELECT Row,Parent,Node,Attribute,ItemType,Value | Export-CSV $fout -NoTypeInformation
}
# End TRY
# Begin Catch
Catch [System.Runtime.InteropServices.COMException]
{
$ErrException = Format-ErrMsg -errmsg $_.Exception
$ErrorMessage = $_.Exception.Message
$ErrorID = $_.FullyQualifiedErrorId
$line = $_.InvocationInfo.ScriptLineNumber
Write-Host " "
Write-Host " "
Write-Host -ForegroundColor DarkMagenta ""
Write-Host -ForegroundColor Magenta "==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!=="
Write-Host -ForegroundColor DarkMagenta ""
Write-Host -ForegroundColor DarkCyan "Details:"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Cyan "`t Module: $modname"
Write-Host -ForegroundColor Cyan "`t Section: $sFunc"
Write-Host -ForegroundColor Cyan "`t On Line: $line"
Write-Host -ForegroundColor Cyan "`t File: $fSearchFile | Search will be skipped!!"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor DarkCyan "Exception Message:"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Yellow "`t ShortMessage: $ErrorMessage"
Write-Host -ForegroundColor Yellow "`t ErrorID: $ErrorID"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Magenta "$ErrException"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor DarkMagenta "========================================================================================================================================== "
Write-Host -ForegroundColor Yellow "This File will be added to the Skip list. Please restart script $sScriptName ...."
Write-Host -ForegroundColor DarkMagenta "========================================================================================================================================== "
Write-Host " "
Write-Host " "
}
Catch
{
$ErrException = Format-ErrMsg -errmsg $_.Exception
$ErrorMessage = $_.Exception.Message
$ErrorID = $_.FullyQualifiedErrorId
$line = $_.InvocationInfo.ScriptLineNumber
Write-Host " "
Write-Host " "
Write-Host -ForegroundColor DarkRed "================================================================================================================================================="
Write-Host -ForegroundColor Red "==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!==!!Error!!=="
Write-Host -ForegroundColor DarkRed "================================================================================================================================================="
Write-Host -ForegroundColor DarkCyan "Details:"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Cyan "`t Module: $modname"
Write-Host -ForegroundColor Cyan "`t Section: $sFunc"
Write-Host -ForegroundColor Cyan "`t On Line: $line"
Write-Host -ForegroundColor Cyan "`t File: $fSearchFile"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor DarkCyan "Exception Message:"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Yellow "`t ShortMessage: $ErrorMessage"
Write-Host -ForegroundColor Magenta "`t ErrorID: $ErrorID"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Red "$ErrException"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
# Show etended error info if in debug mode.
if ($extDebug -eq $true) {
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
Write-Host -ForegroundColor Red "Extended Debugging info"
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
$error[0].Exception | Format-List * -Force
Write-Host -ForegroundColor White "---------------------------------------------------------------------------------------------------------------------------------------------------- "
}
Write-Host -ForegroundColor DarkRed "==================================================================================================================================================== "
Write-Host -ForegroundColor DarkRed "==================================================================================================================================================== "
Write-Host " "
Write-Host " "
Break
# End Catch
}
# Begin Finally
Finally
{
"finis."
Exit 0
# End Finally
}