我最近开始为一家新公司工作,他们之前的技术创建了一个Powershell脚本,旨在从云表单软件的REST API中提取XML数据。它从API中提取相关数据并将其转换为可读的元数据CSV,以附加到我们使用的内部文件管理软件的ADI导入的文件中。我理解脚本是如何工作的,并且它在以前的表单中做得很好。问题在于新表单旨在在单个响应中包含多个条目。如果向此表单添加了多个条目,则脚本不会将数据携带到CSV中。
我是一个Powershell新手,不知道我需要从哪里开始解决这个问题。
我试图删除XML中除了最相关的部分之外的所有部分,以作为我正在使用的内容的示例,这对完整的XML结构进行了相当大的改动。以下是XML数据的两个示例:
<Submission Id="1">
<Form Id="1">
<Name>Example 1</Name>
</Form>
<Section>
<Name>Projected Completion Dates</Name>
<Responses>
<Response Guid="30547A781493817AA0BDBE7C5C6F949A6292FC92">
<Label>Projected Completion Dates</Label>
<Value>04/08/2019</Value>
<Type>Date</Type>
</Response>
</Responses>
</Section>
</Submission>
<Submission Id="2">
<Form Id="2">
<Name>Example 2</Name>
</Form>
<Section>
<Name>Completion Dates</Name>
<Responses>
<Responses Entry="Completion Dates">
<Response Guid="5151F9FC73A03E31B971F38D42CD5300CD6F3C2F">
<Label>Completion Dates</Label>
<Value>04/19/2019</Value>
<Type>Date</Type>
</Response>
<Response Guid="5151F9FC73A03E31B971F38D42CD5300CD6F3C2F">
<Label>Completion Dates</Label>
<Value>04/26/2019</Value>
<Type>Date</Type>
</Response>
</Responses>
</Responses>
</Section>
</Submission>
如果需要,我可以提供整个脚本,但我将尝试将Powershell代码编辑为与XML数据解析相关的代码。
#PARSE XML DATA TO OBJECT
$responses = $parsedXML.SelectNodes("/CanvasResult/Submissions/Submission/Sections/Section/Screens/Screen/Responses/Response")
#CREATE OBJECT THAT MARRIES GOCANVAS XML DATA W/ FILEHOLD METADATA
$objMarry = New-Object -TypeName PSObject
#DYNAMICALLY MARRY LOCAL XML VALUES AND GOCAVNAS API VALUES
foreach ($GCValue in $obj.value){
$objMarry | Add-Member -Type noteProperty `
-Name $GCValue `
-Value ($responses | Where-Object {$_.Label -eq $GCValue} | Select-Object -ExpandProperty Value)
}
在写这篇文章时,我突然意识到,不工作的XML有第二个<Responses>
标记,SelectNodes仅覆盖第一个Responses标记。但是,仅当存在多个条目时才会出现第二个响应标记。因此,如果我正在考虑这个问题,这里的问题是如何调整代码以查找第二个Responses标记并收集该数据以放入CSV。我唯一的想法是添加$multiresponses = $parsedXML.SelectNodes("/CanvasResult/Submissions/Submission/Sections/Section/Screens/Screen/Responses
/ Responses /Response")
并使用if语句检查空值并在那里添加$multiresponses
条目,但我不知道如何编码检查空条目,更不用说添加多个条目并将它们分开_。
所以,总结一下:
预期成绩:
单个条目:来自XML的数据被添加到CSV(在上面的示例1 XML中,条目将是04/08/2019)
多个条目:所有XML条目都添加到CSV并用_分隔(在上面的示例2 XML中,结果将是04/19 / 2019_04 / 26/2019)
实际结果:
单一条目:条目数据被添加到CSV
多个条目:CSV数据为空。
编辑:通过一些研究发现,SelectNodes不需要完整路径,并且通过将PS脚本更改为$responses = $parsedXML.SelectNodes("//Response")
,我现在能够收集所有条目的数据,但它们没有用下划线分隔(示例2会来出于04/19/201904/26/2019)。我已相应调整了问题。
回答了我自己的问题,甚至不知道我是否应该完全删除帖子。这是我对上面相关PS码的调整:
$objMarry | Add-Member -Type noteProperty
-Name $GCValue
-Value ($responses | Where-Object {$_.Label -eq $GCValue} | Select-Object -ExpandProperty Value
| Foreach-Object {$ _ +'_'})
}
从那里,为了删除每个CSV列末尾的任何下划线,我在创建CSV期间添加了一个管道,以替换任何下划线实例,后面跟逗号只用逗号(请参阅下面的代码片段)
$csvobject | ConvertTo-Csv -NoTypeInformation | %{$_ -join ','}| % {$_.Replace('"','')} | %{$_.Replace('_,',',')} | Out-File $CompletedCSV
不知道这是否是最有说服力的方法,但它确实有效。