Борьба с Powershell XML для CSV - PullRequest
0 голосов
/ 25 июня 2018

Я пытаюсь преобразовать файл XML в CSV.Хотя вопрос здесь был полезен, я не смог применить предложения к моему делу - возможно, потому что мои сущности многозначны.Мой Xml выглядит примерно так:

<?xml version="1.0" encoding="UTF-8">
<ReportOutput Version="1">
  <ReportFilters>
    <Filter Name="Report Name" Value="My report"/>
    <Filter Name="Path" Value="/">
    <Filter Name="attr1" Value="*">
    ...
  </ReportFilters>
  <ReportHeader>
    <columnHeader>attr1</columnheader>
    <columnHeader>attr2</columnheader>
    <columnHeader>attr3</columnheader>
    ...
  </ReportHeader>
  <ReportRecord>
    <item>1</item>
    <item>first</item>
    <item>A</item>
    ...
  </ReportRecord>
  <ReportRecord>
    <item>2</item
    <item>second</item>
    <item>B</item>
    ...
  </ReportRecord>
  ...
</ReportOutput>
(where '...' represents one or recurrences of the previous node pattern)

XML - это просто тонкая оболочка, представляющая собой набор табличных данных - все узлы ReportHeader и ReportRecord содержат одинаковое количество дочерних узлов.

Мне нужны элементы ReportHeader.columnHeaders и ReportRecord.It в моем CSV-файле:

attr1, attr2, attr3 ...
1, first, A ...
2, second, B ...

Я могу достаточно легко удалить ReportFilters:

[xml]$xml = Get-Content data.xml

$filter=$xml.ReportOutput.ReportFilters
$filter.ParentNode.RemoveChild($filter)

, но итерация по даннымнемного сложнее.

$xml.ReportOutput.ChildNodes | Export-Csv "C:\Temp\report.csv" -NoTypeInformation -Delimiter:"," -Encoding:UTF8

Первая запись в CSV-файле - это единственный атрибут columnHeader, вторая запись - System.Object [], после этого множество пустых строк.

 {
    $xml.ReportOutput.ReportHeader | ConvertTo-Csv -NoTypeInformation -Delimiter:","
    foreach ($r in $xml.ReportRecord) {
    $r | ConvertTo-Csv -NoTypeInformation -Delimiter:","
    }
} | Set-Content -Path "C:\Temp\report.csv" -Encoding:UTF8

записал часть исходного кода в выходной поток.

 $xml.ReportOutput.ReportHeader | ConvertTo-Csv -NoTypeInformation -Delimiter:"," | Set-Content -Path "C:\Temp\report.csv" -Encoding:UTF8
 foreach ($r in $xml.ReportOutput.ReportRecord) {
    $r | ConvertTo-Csv -NoTypeInformation -Delimiter:"," | Add-Content -Path "C:\Temp\report.csv" -Encoding:UTF8
 }

просто написал много бреда.

 $xml.ReportOutput.ReportHeader.ChildNodes | ConvertTo-Csv -NoTypeInformation -Delimiter:"," | Set-Content -Path "C:\Temp\report.csv" -Encoding:UTF8
 foreach ($r in $xml.ReportOutput.ReportRecord) {
    $r.ChildNodes | ConvertTo-Csv -NoTypeInformation -Delimiter:"," | Add-Content -Path "C:\Temp\report.csv" -Encoding:UTF8
 }

имел данные - но как единое целоеатрибут на запись

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Грег (превосходное) решение использует сращивание строк для создания прототипа CSV-файла (в $ csv), а затем преобразует его обратно в коллекцию powershell, а затем в CSV в качестве этапа очистки. Метод сращивания строк не очень сложен, и все становится запутанным, если входные данные содержат вещи, которые рассматриваются как метаданные CSV (то есть запятые). Поэтому я нашел более безопасным использовать символ табуляции:

$csv = @(($xml = [xml](Get-Content C:\path\input.xml)).SelectNodes('//columnHeader').'#text' -join "`t")
$csv += $xml.SelectNodes('//ReportRecord').ForEach{$_.item -join "`t"}
$csv | ConvertFrom-Csv -Delimiter "`t" | Export-Csv C:\path\output.csv

Это не совсем надежно, но достаточно хорошо для меня.

0 голосов
/ 25 июня 2018

Я искренне верю, что ваш XML-документ действителен и все закрывающие теги в нем верны (как подсказка). Итак ...

# create header of the future CSV (attr1,attr2,attr3...)
$csv = @(($xml = [xml](Get-Content C:\path\input.xml)).SelectNodes('//columnHeader').'#text' -join ',')
# append lines to the future CSV
$csv += $xml.SelectNodes('//ReportRecord').ForEach{$_.item -join ','}
# at present moment $csv is the array
# attr1,attr2,attr3...
# 1,first,A...
# 2,second,B...
# time to write this data as CSV on disk
$csv | ConvertFrom-Csv | Export-Csv C:\path\output.csv

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...