繁体   English   中英

Powershell脚本可导入,拼合和合并多个xml文件并导出为csv

[英]Powershell script to import, flatten and merge multiple xml files and export as csv

各位勇敢的编码人员,您好,我需要整理,合并并转换为csv文件的大量xml文件,以导入到Excel中,然后将数据映射到另一个数据集中以用于更大的数据迁移。

我设法产生了一个脚本,该脚本收集给定文件夹中的所有xml文件,并将第一级元素输出到收集的csv文件中的新行。 问题是xml文件的结构(无法更改)。 这是XML的示例:


<!-- language: lang-xml -->
<?xml version='1.0' encoding='UTF-8'?>

<tmf_study_item>
  <a_acl_id type="String">0021AC7A0000000000081FDC</a_acl_id>
  <a_created_by type="String">xxxxxxxx</a_created_by>
  <ad_document_date type="LocalDate">2016-04-07</ad_document_date>
  <documents>
    <tmf_document>
      <a_acl_id type="String">0021AC7A00000000000823B1</a_acl_id>
      <a_acl_name type="String">TMF Study AC-064A201-Lupus Document Final ACL</a_acl_name>
      <a_modified_date type="Date">2016-04-19 05:28:06.708</a_modified_date>
      <multi_index_data>
        <multi_index_data>
          <amendment_number type="String"></amendment_number>
          <artifact_num type="String">01.05.03</artifact_num>
          <committee_type_code type="String"/>
        </multi_index_data>
      </multi_index_data>
      <related_placeholders>
      </related_placeholders>
      <shared_user>
      </shared_user>
      <workflow_user>
      </workflow_user>
      <contents>
        <content>
          <path>very_long_document_title1.pdf</path>
          <fileName>very_long_document_title1.pdf</fileName>
          <contentTypeId>pdf</contentTypeId>
          <mimeType>application/pdf</mimeType>
        </content>
        <content>
          <path>very_long_document_title1.docx</path>
          <fileName>very_long_document_title1.docx</fileName>
          <contentTypeId>word_docx</contentTypeId>
          <mimeType>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mimeType>
        </content>
      </contents>
    </tmf_document>
  </documents>
</tmf_study_item>

您会注意到,某些文件中的最后一些元素出现两次,并且可能还会更多。 因此,我需要知道的是如何扁平化此xml层次结构,并以[parent.element] [iteration] [childelement]的形式为子元素提供唯一的名称,同时考虑到子元素的数量变化,并且应该可以导出到csv。 子项目的唯一标头对于随后在excel中正确进行映射是必要的。

这是我到目前为止编写的代码,我很笨拙地尝试做的是先处理1级元素,然后再处理“ tmf_document”元素,将它们连接起来,然后导出为CSV。 但是由于某种原因,我无法弄清楚我得到的错误:“添加成员:无法添加名称为[基本上是所有元素]的成员,因为具有该名称的成员已经存在。” 编码:

# Get all XML files
$rootElement = "tmf_study_item"
$documentElement = "tmf_document"
$midElement = "multi_index_data"
$items = Get-ChildItem *.xml
$scriptPath = $(get-location).Path
$scriptFolder = split-path $(get-location).Path -Leaf
$outputFile = $scriptPath+"\"+$scriptFolder+".csv"

# Loop through xmls and append them to the document
foreach ($item in $items) {
# Create filename for single CSV
$baseNameoutputFile = $scriptPath+"\"+(Get-ChildItem $item).BaseName+".csv"

[XML]$xml = (Get-Content $item) #load xml document
[Array]$RootitemConverted = $xml.GetElementsByTagName($rootElement)

# Create array for document elements
[Array]$DocConverted = $xml.GetElementsByTagName($documentElement)

# Create array for multi_index_data
[Array]$MidConverted = $xml.GetElementsByTagName($midElement)

$Collection = @()
Write-host "Start processing new XML >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"

# Loop over 1st level elements in XML------------------------------------------------------------
ForEach($Record in $RootitemConverted){

$Output = new-object psobject

$Record.selectnodes("*")|%{
Add-Member -InputObject $Output -MemberType NoteProperty -Name $_.Name -Value $_.'#text'
}

Write-host "Add data to PSobject and collection >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"

If($Collection){
$T2Keys = $Collection|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$T1Keys = $Output|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$KeysToAdd = $T2Keys|?{$T1Keys -notcontains $_}
$KeysToAdd|%{$Collection|Add-Member $_ ""}
}

$Collection += $Output
}


# Loop over documents level elements in XML-----------------------------------------------------------------
ForEach($Documents in $DocConverted){

$DocOutput = new-object psobject
#Add Prefix to document-elements
$Documents.selectnodes("*")|%{
$tmpName = $_.Name
$tmpName = $documentElement+"_1_"+$tmpName
Write-Host $tmpName
Add-Member -InputObject $DocOutput -MemberType NoteProperty -Name $tmpName -Value $_.'#text'
}

Write-host "Add data to PSobject and collection >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"

If($Collection){
$T2Keys = $Collection|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$T1Keys = $DocOutput|gm|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
$KeysToAdd = $T2Keys|?{$T1Keys -notcontains $_}
$KeysToAdd|%{$Collection|Add-Member $_ ""}
}

$Collection += $DocOutput
}

$Collection

# Append to CSV File
$Collection | Export-Csv -path $outputFile -Delimiter ";" -NoTypeInformation -Append

# Create a CSV for each file
#$Collection | Export-Csv -path $baseNameoutputFile -Delimiter ";" -NoTypeInformation
}

我希望你们中的一些人能给我一些有关如何解决这个问题的指示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM