2016-10-20 18 views
1

我當前的代碼,選擇XML中的某些屬性似乎不工作:如何分別輸出子元素,而不是一個空格分隔的字符串?

[xml]$xml = Get-Content 'C:\Makro-Test\quandata.xml' 
$xml.QUANDATASET.GROUPDATA.GROUP.SAMPLELISTDATA.SAMPLE | foreach { 
    $_.id + ":" + $_.name + ":" + $_.COMPOUND.id + ":" + $_.COMPOUND.name + 
    ":" + $_.COMPOUND.PEAK.analconc 
} 

它輸出:

1:Aminoacids_Routine_2016_05_30_002:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23:Leu Iso Thre Val Lys Met Phen Try His Gly Ala Ser Arg Cys Tyr Pro Glu Glut Asp Aspa Tau Orn Cit:0.0000000000  0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 
2:Aminoacids_Routine_2016_05_30_003:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23:Leu Iso Thre Val Lys Met Phen Try His Gly Ala Ser Arg Cys Tyr Pro Glu Glut Asp Aspa Tau Orn Cit:0.0000000000 0.2336617286 0.2147717292 0.2252815136 0.2299108827 0.2395318825 0.0000000000 0.0000000000 0.0000000000 0.2074479299  0.0000000000 0.0000000000

但我所要的輸出看起來像:

1;Aminoacids_Routine_2016_05_30_002;1;Leu;0.0000000000 
2;Aminoacids_Routine_2016_05_30_002;2;Iso;0.0000000000 
... 
1;Aminoacids_Routine_2016_05_30_003;1;Leu;0.0000000000 
2;Aminoacids_Routine_2016_05_30_003;2;Iso;0.2336617286 
...

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

回答

1

您並未使用XPath selectors,而是使用本機PowerShell對象屬性訪問權限。

PowerShell 3.0和更高版本在整個數組上使用時會自動生成指定屬性值的數組。

在XML的情況下,每個重複的元素(如COMPOUND)在按名稱訪問時(即沒有索引)返回數組,因此上述行爲適用於$_.COMPOUND.id:這是一個數組!並且通過將代碼中的空格加入元素,它會自動強制類型化爲一個字符串。

解決方案1:列舉手動子元素:

$delim = ':' 
foreach ($sample in $xml.QUANDATASET.GROUPDATA.GROUP.SAMPLELISTDATA.SAMPLE) { 
    foreach ($compound in $sample.COMPOUND) { 
     $sample.id, $sample.name, 
     $compound.id, $compound.name, [double]$compound.PEAK.analconc -join $delim 
    } 
} 

解決方案2:實際使用XPath來選擇所有子元素和訪問SAMPLEparentNode

$delim = ':' 
foreach ($compound in $xml.SelectNodes('//COMPOUND')) { 
    $sample = $compound.ParentNode 
    $sample.id, $sample.name, 
    $compound.id, $compound.name, [double]$compound.PEAK.analconc -join $delim 
} 

代替流水線我使用foreach聲明有一個很好命名的迭代器變量。

+0

感謝這個真正有用的答案和解釋!這正是我正在尋找的東西,並且我還學到了一些東西。謝謝 – Benhur262

+0

當數組類型被強制轉換爲一個字符串時,元素不會被空格連接,而是被'$ OFS':'$ OFS ='not_space'; [string](1..3)'連接。 – PetSerAl

+0

很高興知道。準確地說:除非您更改$ OFS的默認值,即$ null,否則元素將由空格字符連接。 – wOxxOm

2

@wOxxOm我會使用SelectNodes()XPathexpression,但我會處理輸出爲calculated properties代替:

$xml.SelectNodes('//COMPOUND') | 
    Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}}, 
       @{n='SampleName';e={$_.ParentNode.name}}, 
       @{n='CompoundID';e={[int]$_.id}}, 
       @{n='CompoundName';e={$_.name}}, 
       @{n='analconc';e={[double]$_.PEAK.analconc}} 

這會給你用的對象,而不是一個字符串的工作。如果你需要寫入文件中的數據可以通過Export-Csv導出:

... | Export-Csv 'C:\path\to\quandata.csv' -NoType -Delimiter ';' 
+0

謝謝你的詳細補充。 導出爲CSV的選項,我將能夠使用最好的。 – Benhur262

+0

請在發佈的問題中看到我的編輯,關於處理幾個xml文件到csv ... – Benhur262

+0

@ Benhur262請不要移動目標。如果您有新的或後續問題:發佈新問題。 –

相關問題