Как проанализировать список пар имя-значение, разделенных запятыми, в массив хэш-таблиц

#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>