Недавно я начал работать в новой компании, и их прежний технический специалист создал сценарий Powershell, предназначенный для извлечения XML-данных из REST API программного обеспечения облачных форм. Он извлекает соответствующие данные из API и превращает их в удобочитаемый CSV метаданных для прикрепления к файлу, импортированному ADI внутреннего программного обеспечения для управления файлами, которое мы используем. Я понимаю, как работает скрипт, и он прекрасно работал с предыдущими формами. Проблема связана с новой формой, которая предназначена для нескольких записей в одном ответе. Если в эту форму добавлено несколько записей, сценарий не переносит данные в CSV.
Я новичок в Powershell и понятия не имею, с чего мне нужно начать, чтобы решить эту проблему.
Я попытался удалить все части XML, кроме наиболее подходящих, чтобы использовать их в качестве примеров того, с чем я работаю, что вносит довольно большое изменение в полную структуру XML. Вот 2 примера данных 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. Однако второй тег ответов появляется только при наличии нескольких записей. Итак, если я думаю об этом правильно, проблема заключается в том, как настроить код для поиска второго тега ответов и собрать эти данные, чтобы поместить их в CSV. Моя единственная мысль - добавить $multiresponses = $parsedXML.SelectNodes("/CanvasResult/Submissions/Submission/Sections/Section/Screens/Screen/Responses
/Ответы/Response")
и использовать оператор if для проверки нулевых значений и добавления туда записей $multiresponses
, но я не знаю, как кодировать проверку нулевых записей, не говоря уже о том, чтобы добавить несколько записей и разделить их с помощью _ .
Итак, резюмируя:
Ожидаемые результаты:
Одиночная запись: данные из XML добавляются в CSV (в примере 1 XML выше запись будет 08.04.2019)
Несколько записей: все записи XML добавляются в CSV и разделяются знаком _ (в приведенном выше примере 2 XML результатом будет 19.04.2019_26.04.2019)
Фактические результаты:
Единая запись: данные записи добавляются в CSV
Несколько записей: данные CSV пусты.
Обновлено: в результате некоторых исследований выяснилось, что полный путь не требуется для SelectNodes и что, изменив сценарий PS на $responses = $parsedXML.SelectNodes("//Response")
, я теперь могу собирать данные для всех записей, но они не разделены символом подчеркивания (Пример 2 придет по состоянию на 19.04.2019026.04.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
Не знаю, является ли это самым красноречивым способом добиться этого, но он работает.
попробуй
-Value (($responses | Where-Object {$_.Label -eq $GCValue} | Select-Object -ExpandProperty Value) -join '_')