#powershell #csv #key-value
Вопрос:
У меня есть файл данных в формате:
"field1=value1","field2=data containing a ""double quote""","field3=data, with a comma"
"field1=value2","field4=more data"
Не каждая строка имеет одинаковую длину, не в каждой строке есть одинаковые поля. Я пытаюсь проанализировать его в массив хэш-таблиц, в конечном счете, чтобы преобразовать его в XML как:
<file>
<row>
<field1>value1</field2>
<field2>data containing a "double quote"</field2>
<field3>data, with a comma</field3>
</row>
<row>
<field1>value2</field1>
<field4>more data</field4>
</row>
</file>
Я совершенно уверен, что смогу вывести XML из массива хэш-таблиц, а если не смогу, это будет отдельный вопрос! Но как мне проанализировать это в первую очередь, соблюдая отступ «» и запятые в полевых данных?
При синтаксическом анализе с использованием ConvertFrom-StringData
поля должны располагаться в отдельных строках, а не разделяться запятыми, и разделение с помощью Import-Csv
не разбивает пары имя-значение.
Комментарии:
1.
"field1=value1","field2=data containing a ""double quote""","field3=data, with a comma" |ConvertFrom-StringData
2. Теперь это то, что я думал, произойдет, но, похоже, это не работает, когда я читаю файл в использовании
foreach ($line in <filename>) { $line | ConvertFrom-StringData }
3. (Чтобы уточнить, я действительно это сделал
foreach ($line in Get-Content <filename>)
, забыл этот кусочек.4. Хорошо, после небольшого исследования прямой ввод строки таким образом фактически передает массив в ConvertFrom-StringData; каждая строка файла-это просто строка.
5. И нет, я не могу использовать-разделить «,», это неправильно обработает запятую в данных.
Ответ №1:
$Data = # Get-Content .Data.txt
'"field1=value1","field2=data containing a ""double quote""","field3=data, with a comma"',
'"field1=value2","field4=more data"'
$Xml = [System.Xml.XmlDocument]::new()
$File = $Xml.AppendChild($Xml.CreateElement('file'))
foreach ($Line in $Data) {
$Row = $File.AppendChild($Xml.CreateElement('row'))
$Items = ($Line |ConvertFrom-Csv -Header (0..9)).PSObject.Properties.Value.Where{$_}
foreach ($Item in $Items) {
$Name, $Value = $Item.Split('=', 2)
$Field = $Row.AppendChild($Xml.CreateElement($Name))
$Field.InnerText = $Value
}
}
$Xml.outerxml
<file><row><field1>value1</field1><field2>data containing a "double quote"</field2><field3>data, with a comma</field3></row><row><field1>value2</field1><field4>more data</field4></row></file>