Powershell CSV в XML - PullRequest
       10

Powershell CSV в XML

0 голосов
/ 24 октября 2018

Итак, я пытаюсь преобразовать CSV-файл в XML, который содержит 5 столбцов:

UserID;Cert;LastCertDate;ExpireDate;CertNumber
100001;oka;09.09.2018;09.09.2019;100001
100001;pik;10.10.2018;10.10.2019;200001

Структура XML должна быть следующей:

<Cv>
    <Owner>
        <UserID></UserID>
    </Owner>
    <Content>
        <Certificates>
            <Certificate>
                <Cert>oka</Cert>
                <LastCertDate>09.09.2018</LastCertDate>
                <ExpireDate>09.09.2019</ExpireDate>
                <CertNumber>100001</CertNumber>
            </Certificate>
            <Certificate>
                <Cert>pik</Cert>
                <LastCertDate>10.10.2018</LastCertDate>
                <ExpireDate>10.10.2019</ExpireDate>
                <CertNumber>200001</CertNumber>
            </Certificate>
        </Certificates>
    </Content>
</Cv>

На данный момент ятолько удалось получить 2-й сертификат в XML, так как он находится в строке в файле CSV.

Есть идеи, как можно объединить идентификатор пользователя и создать список, содержащий все сертификаты для этого конкретного пользователя?

Спасибо!

1 Ответ

0 голосов
/ 25 октября 2018

Беконные биты дали критический указатель в комментарии: используйте Group-Object, чтобы сгруппировать пользовательские объекты, созданные из строк CSV, через Import-Csv по идентификатору пользователя.

Вот решениекоторый использует строковые шаблоны для предоставления желаемого текстового вывода XML для каждого пользователя и записывает этот вывод в файл с именем пользователя с идентификатором:

# Per-user template.
# Note how a *literal* (single-quoted) here-string is used, so as to 
# *defer* expansion (interpolation) of the embedded expressions.
$docTemplate = @'
<Cv>
  <Owner>
      <UserID>$($cert.UserID)</UserID>
  </Owner>
  <Content>
      <Certificates>
$($certs -join "`n")
      </Certificates>
  </Content>
</Cv>
'@

# Per-certificate template.
$entryTemplate = @'
          <Certificate>
            <Cert>$($cert.Cert)</Cert>
            <LastCertDate>$($cert.LastCertDate)</LastCertDate>
            <ExpireDate>$($cert.ExpireDate)</ExpireDate>
            <CertNumber>$($cert.CertNumber)</CertNumber>
          </Certificate>
'@

Import-Csv file.csv -Delimiter ';' | Group-Object UserId -ov grp | ForEach-Object {
  # $_.Group contains all certificates associated with the user at hand.
  # Create an XML element for each certificate and collect the results
  # in array.
  $certs = foreach ($cert in $_.Group) {
    # Instantiate the per-certificate template.
    $ExecutionContext.InvokeCommand.ExpandString($entryTemplate)  
  }
  # Instantiate the per-user template, which encompasses
  # the per-certificate elements, and output the result.
  $ExecutionContext.InvokeCommand.ExpandString($docTemplate)
} | # Write the resulting XML document string to a file named for the user ID
  Set-Content -LiteralPath { $grp.Name + '.xml' }

Обратите внимание, как -ov grp (сокращение от: -OutVariable grp)захватывает вывод Group-Object в каждой итерации конвейера в переменную $grp, так что вызов Set-Content позже в конвейере может получить доступ к $grp.Name - идентификатору пользователя под рукой - в блоке сценария, переданном Set-Content, поэтомукак для создания выходного файла с именем для идентификатора пользователя.

Примечание. Без аргумента -Encoding Windows PowerShell будет использовать кодировку символов вашей системы «ANSI» (в PowerShell Core выполучит без спецификации UTF-8).

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