我有一个脚本,该脚本基于.csv生成xml文件,该脚本将通过网络服务(RESTapi)充当有效负载。
有效载荷要求我生成一些GUID,只要我生成新的GUID就可以。为了通过API成功更新数据,我需要指定接收系统中每个用户已经存在的GUID。
因此,我要做的第一件事是向系统发出GET请求以导出所有用户。 然后,我根据GET请求中的.xml检查生成的.xml文件中的用户。
如果用户匹配,我想将导出中存在的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>
由于“ aa”是一个匹配项,因此我需要以下输出:
<CVs>
<CV>
<GUID>800b96cd-56e9-4587-a9db-41c2a4095d04</GUID>
<EMPLOYEE>
<IDENTIFIER>aa</IDENTIFIER>
</EMPLOYEE>
</CV>
</CVs>
这是我生产所有内容的工作代码,但如果两个节点匹配,则从另一个.xml获取该GUID。
$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')
答案 0 :(得分:0)
如果我正确地理解了要点,则您想要创建一个新的Guid或使用从包含所有现有用户/ guid列表的XML文件中获取的现有guid。
这是一个有关如何读取文件的最小示例(我在此处使用了此处的字符串代替),将其解析为用户/ guid列表,然后检查接收到的用户是否在现有XML中,以及获取相应的GUID或创建一个新的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还是创建新GUID。
答案 1 :(得分:0)
就像 @ 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
}
解决问题。
谢谢!