Значение XML-узла PowerShell из другого файла, ЕСЛИ другие узлы -match - PullRequest
0 голосов
/ 25 мая 2019

У меня есть скрипт, который генерирует XML-файл на основе .csv, который будет работать как полезная нагрузка через веб-сервис (RESTapi).

Полезная нагрузка требует от меня создания некоторых GUID, которые хороши, еслиЯ генерирую новые.Чтобы успешно обновить данные через API, мне нужно указать GUID, который уже существует для каждого пользователя в принимающей системе.

Итак, первое, что я делаю, - это запрос GET к системе на экспорт всех пользователей.Затем я проверяю пользователей в моем сгенерированном файле .xml на соответствие .xml из запроса GET.

Если пользователи совпадают, я хочу извлечь GUID, существующий при экспорте, в мой сгенерированный вывод.И вот где я застрял.

Например, я бы сопоставил:

<CVs>
  <CV>
    <GUID></GUID>
    <EMPLOYEE>
        <IDENTIFIER>aa</IDENTIFIER>
    </EMPLOYEE>
  </CV>
</CVs>

Против:

    <CV>
        <GUID>800b96cd-56e9-4587-a9db-41c2a4095d04</GUID>
        <EMPLOYEE>
           <USERNAME>aa</USERNAME>
        </EMPLOYEE>
    </CV>
    <CV>
        <GUID>a07ac517-c7d5-4766-89b6-9101260f6f53</GUID>
        <EMPLOYEE>
           <USERNAME>bb</USERNAME>
        </EMPLOYEE>
    </CV>
    <CV>
        <GUID>84d82720-3e06-4802-9206-69f25b2aa46d</GUID>
        <EMPLOYEE>
           <USERNAME>cc</USERNAME>
        </EMPLOYEE>
    </CV>
  </CVs>

А так как "аа" являетсясовпадение, я хотел бы получить следующий вывод:

<CVs>
  <CV>
    <GUID>800b96cd-56e9-4587-a9db-41c2a4095d04</GUID>
    <EMPLOYEE>
        <IDENTIFIER>aa</IDENTIFIER>
    </EMPLOYEE>
  </CV>
</CVs>

Это мой рабочий код для создания всего, кроме получения этого GUID из другого .xml, если совпадают два узла.

$docTemplate = @'
  <CV>
    <GUID></GUID>
    <EMPLOYEE>
        <IDENTIFIER>$($cert.Identifier)</IDENTIFIER>
    </EMPLOYEE>
    <PAGE id="8">
  $($certs -join "`n")
    </PAGE>
  </CV>
'@

# Per-certificate template.
$entryTemplate = @'
    <RECORD>
      <GUID></GUID>
      <FIELD id="21">
        <DATA>
          <GUID></GUID>
          <VALUE>$($cert.Certificate)</VALUE>
        </DATA>
      </FIELD>
      <FIELD id="36">
        <DATA><VALUE>$($cert.From)</VALUE></DATA>
      </FIELD> 
      <FIELD id="22">$($cert.ExpireDate)
        <DATA><VALUE>$($cert.to)</VALUE></DATA>
      </FIELD>
    </RECORD>
'@

$cvData = Import-Csv demo.csv -Delimiter ';' | Group-Object Identifier -ov grp | ForEach-Object {

  $certs = foreach ($cert in $_.Group) {
    $ExecutionContext.InvokeCommand.ExpandString($entryTemplate)  
  }
  $ExecutionContext.InvokeCommand.ExpandString($docTemplate)
}

$rootTemplate = @'
<CVs>
$($cvData -join "`n")
</CVs>
'@
$output = $ExecutionContext.InvokeCommand.ExpandString($rootTemplate) | Set-Content -LiteralPath 'cvoutput.xml'



#Add GUID
$xmlFile = '.\cvoutput.xml'
[xml]$xmlDoc = Get-Content $xmlFile

#Add Record GUID
foreach ($element in $xmlDoc.CVs.CV.PAGE.RECORD)
{
    [string]$element.GUID = New-Guid
}

#Check if Node exists (certifications require a GUID in the Cert Data Node)
foreach ($element in $xmlDoc.CVs.CV.PAGE.RECORD.FIELD | Where-Object  {$_.name -match "Certifications"}) {
  [string]$element.DATA.GUID = New-Guid
}


$xmlDoc.Save('cv-data.xml')

Ответы [ 2 ]

0 голосов
/ 26 мая 2019

Так же, как @ sage-pourpre предлагает:
$Nodes = $XML.SelectNodes('//CV') | Select @{'Name' = 'EmployeeID' ; 'Expression' = { $_.EMPLOYEE.USERNAME } }, GUID

С:
foreach ($emp in $xmlDoc.CVs.CV ) { $Guid = $Nodes | Where EmployeeID -eq ($emp.EMPLOYEE.IDENTIFIER) | Select -First 1 [string]$emp.GUID = $Guid.GUID }

Решает проблему.

Спасибо!

0 голосов
/ 26 мая 2019

Если я правильно понял суть, вы хотите либо создать новый guid, либо использовать существующий guid, полученный из файла XML, содержащего список всех существующих пользователей / гидов.

Вот минимальный пример того, как вы читаете файл (вместо этого я использовал здесь строку), анализируете его как список user / guid, затем проверяете, находится ли полученный пользователь в существующем XML, и получить соответствующий GUID или создать новый.

.

$OutTemplate = @"
<CVs>
  <CV>
    <GUID>{0}</GUID>
    <EMPLOYEE>
        <IDENTIFIER>{1}</IDENTIFIER>
    </EMPLOYEE>
  </CV>
</CVs>
"@

$AllUsers = @"
<CVS>
  <CV>
        <GUID>800b96cd-56e9-4587-a9db-41c2a4095d04</GUID>
        <EMPLOYEE>
           <USERNAME>aa</USERNAME>
        </EMPLOYEE>
    </CV>
    <CV>
        <GUID>a07ac517-c7d5-4766-89b6-9101260f6f53</GUID>
        <EMPLOYEE>
           <USERNAME>bb</USERNAME>
        </EMPLOYEE>
    </CV>
    <CV>
        <GUID>84d82720-3e06-4802-9206-69f25b2aa46d</GUID>
        <EMPLOYEE>
           <USERNAME>cc</USERNAME>
        </EMPLOYEE>
    </CV>
  </CVS>
"@


#   From File 
#   $XML = [xml](Get-Content -Path 'PathToXML.xml' -Raw)

$XML = [xml]$Allusers
$Nodes = $XML.SelectNodes('//CV') | Select @{'Name' = 'EmployeeID' ; 'Expression' = { $_.EMPLOYEE.USERNAME } }, GUID

# Instead of a fixed array, you'd have your received users here.
$Employees = @('aa', 'csd', 'ee')

foreach ($emp in $employees) {
    $Guid = $Nodes | Where EmployeeID -eq ($emp) | Select -First 1
    if ($Guid -eq $null) {
        $Guid = New-Guid
        $Color = 'DarkMagenta'
    }
    else {
        $Color = 'Cyan'
        $Guid = $Guid.Guid
    }

    $OutElement = $OutTemplate -f $guid, $emp

    Write-Host $OutElement -ForegroundColor $Color

}

Важной частью этого примера является:

$Nodes = $XML.SelectNodes('//CV') | Select @{'Name' = 'EmployeeID' ; 'Expression' = { $_.EMPLOYEE.USERNAME } }, GUID

Оттуда у вас есть список существующих GUID пользователей, и вы можете обработать все записи в нем и решить, использовать ли существующий GUID или создать новый.

...