我有一个良好的PowerShell脚本(感谢Ansgar Wiechers)获得一个XML文件,它将所需的字段导出到CSV文件:
$goal = '\\LC\ARCHIV\INPUT_' + (Get-Date -Format yyyyMMddss) + '.xml'
[xml]$xml = Get-Content '\\mcsonlines-impexp\Onlines\LCMS\IMPORT\*.xml'
$xml.SelectNodes('//COMPOUND') |
Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
@{n='SampleName';e={"B" + $_.ParentNode.name}},
@{n='CompoundID';e={[int]$_.id}},
@{n='CompoundName';e={$_.name}},
@{n='analconc';e={[double]$_.PEAK.analconc}} |
Export-Csv '\\LC\IMPORT\quandata.csv' -NoType -Delimiter ';'
Move-Item -Path \\LC\IMPORT\*.xml -destination $goal
XML文件:
<?xml version="1.0"?>
<QUANDATASET>
<XMLFILE>
<DATASET>
<GROUPDATA>
<GROUP>
<METHODDATA/>
<SAMPLELISTDATA>
<SAMPLE id="1" groupid="1" name="Routine_2016_05_30_002">
<COMPOUND id="1" sampleid="1" groupid="1" name="Leu">
<PEAK foundscan="0" analconc="0.023423456">
<ISPEAK/>
</PEAK>
</COMPOUND>
<COMPOUND id="2" sampleid="1" groupid="1" name="Iso">
<PEAK foundscan="0" analconc="0.123456789">
<ISPEAK/>
</PEAK>
</COMPOUND>
<COMPOUND id="3" sampleid="1" groupid="1" name="Thre">
...
...
...
<SAMPLE id="2" groupid="1" name="Routine_2016_05_30_003">
<COMPOUND id="1" sampleid="2" groupid="1" name="Leu">
...
...
...
CSV导出如下:
SampleID SampleName CompoundID CompoundName analconc ... 6 Routine_2016_11_11_006 1 Leu 60,30064828 6 Routine_2016_11_11_006 2 Iso 60,38823887 6 Routine_2016_11_11_006 3 Thre 74,00187964 ...
现在我的问题 - 是否可以使用脚本一次处理多个XML文件到CSV文件?我的改变使得剧本一点都没有。
首先尝试:
$file = Get-ChildItem '\\LC\IMPORT\*.xml' -Recurse
foreach ($file in $files) {
[xml]$xml = (Get-Content $file)
$xml.SelectNodes('//COMPOUND') |
Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
@{n='SampleName';e={"B" + $_.ParentNode.name}},
@{n='CompoundID';e={[int]$_.id}},
@{n='CompoundName';e={$_.name}},
@{n='analconc';e={[double]$_.PEAK.analconc}} |
Export-Csv '\\LC\IMPORT\quandata.csv' -NoType -Delimiter ';'
}
这根本不起作用。
第二次尝试:
Get-ChildItem '\\LC\IMPORT\' *.xml -Recurse | % {
$xml = [xml](Get-Content $_.FullName)
#$goal = '\\LC\ARCHIV\INPUT_' + (Get-Date -Format yyyyMMddss) + '.xml'
$xml.SelectNodes('//COMPOUND') |
Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
@{n='SampleName';e={"B" + $_.ParentNode.name}},
@{n='CompoundID';e={[int]$_.id}},
@{n='CompoundName';e={$_.name}},
@{n='analconc';e={[double]$_.PEAK.analconc}} |
Export-Csv '\\LC\IMPORT\quandata.csv' -NoType -Delimiter ';'
}
通过此尝试,只有一个XML文件导出到CSV文件。
这是我第一篇文章的链接:
How to output child elements separately, not as one space-delimited string?
答案 0 :(得分:1)
您总是覆盖csv文件,请使用:
[..]Export-Csv '\\LC\IMPORT\quandata.csv' -NoType -Delimiter ';' -Append
代替。 -Append
将导致PowerShell添加新内容。
答案 1 :(得分:0)
您的第一种方法没有做任何事情,因为您收集变量$file
中的XML文件列表,但随后迭代变量$files
(注意尾随的“s”),这是空。
你的第二种方法会在每次迭代时覆盖输出文件,因为你在1>} 循环中使用了Export-Csv
而没有参数-Append
。
在循环之后放置Export-Csv
语句:
Get-ChildItem '\\LC\IMPORT\*.xml' -Recurse | ForEach-Object {
[xml]$xml = Get-Content $_.FullName
$xml.SelectNodes('//COMPOUND') |
Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
@{n='SampleName';e={"B" + $_.ParentNode.name}},
@{n='CompoundID';e={[int]$_.id}},
@{n='CompoundName';e={$_.name}},
@{n='analconc';e={[double]$_.PEAK.analconc}}
} | Export-Csv '\\LC\IMPORT\quandata.csv' -NoType -Delimiter ';'
或使用参数Export-Csv
在循环中调用-Append
,以便每次迭代都附加到CSV:
Get-ChildItem '\\LC\IMPORT\*.xml' -Recurse | ForEach-Object {
[xml]$xml = Get-Content $_.FullName
$xml.SelectNodes('//COMPOUND') |
Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
@{n='SampleName';e={"B" + $_.ParentNode.name}},
@{n='CompoundID';e={[int]$_.id}},
@{n='CompoundName';e={$_.name}},
@{n='analconc';e={[double]$_.PEAK.analconc}} |
Export-Csv '\\LC\IMPORT\quandata.csv' -Append -NoType -Delimiter ';'
}
第一种方法更可取,因为它避免重复打开和关闭输出文件,因此它具有更好的性能。此外,参数-Append
在PowerShell v3之前不可用,因此第二种方法至少需要PowerShell版本,并且无法在PowerShell v2或更早版本上运行。