Объединить несколько XML в нескольких подпапках с помощью Powershell - PullRequest
0 голосов
/ 10 февраля 2020

Я новичок в PowerShell. В настоящее время я борюсь со следующей настройкой. В этой структуре папок содержится несколько XML файлов:

Root
|_2020-XX-XX
   |_file1.xml
   |_file2.xml
|_2020-yy-yy
    |_file1.xml
    |_file2.xml

Теперь я хочу создать скрипт, который объединяет части файлов xml каждой папки в один.

результат должен выглядеть примерно так:

|_2020-XX-XX
   |_file1.xml
   |_file2.xml
   |_newfile2020XXXX.xml
|_2020-yy-yy
    |_file1.xml
    |_file2.xml
    |_newfile2020YYYY.xml

Пока мой скрипт выглядит так:

$date=Get-Date -Format "yyyyMMdd"
#Get the date for naming the output-file

$xmlFilePath = Get-ChildItem "\\Server\Rootfolder" -Recurse -Force | Sort-Object LastWriteTime
#Get and sort the xml-Files by date

$finalXml = "<root>"

foreach ($file in $_.xmlFilePath) {
    [xml]$xml = Get-Content $file
    $finalXml += $xml.root.InnerXml
}
$finalXml += "</root>"
#XML Object closer

([xml]$finalXml).Save("$pwd\newfile$date.xml")

Хотя отладчик не выдает никакой ошибки, созданный файл

  • также не сохранено в правильном каталоге ("$ pwd" не является правильной переменной)
  • пусто, за исключением узлов <root></root>.

Я не могу понять, что делать, чтобы решить эту проблему, и был бы благодарен за любые советы по этому вопросу.

Заранее благодарен за любую подсказку!

1 Ответ

1 голос
/ 10 февраля 2020

Кажется, вы хотите создать один «объединенный» файл для каждой папки. Это означает, что вам нужно два цикла - один для папок и один для файлов в папке.

$date = Get-Date -Format "yyyyMMdd"

Get-ChildItem "\\Server\Rootfolder" -Directory | ForEach-Object {
    $folder = $_.FullName
    Write-Host "Processing $folder..."

    $allData = [xml]"<root></root>"

    Get-ChildItem $folder -Filter "*.xml" | Sort-Object LastWriteTime | ForEach-Object {
        if ($_.Name -like "newfile*") { return }
        Write-Host " -" $_.name

        $xml = New-Object xml
        $xml.Load($_.FullName)

        $imported = $allData.ImportNode($xml.DocumentElement, $true)
        $allData.DocumentElement.AppendChild($imported) | Out-Null
    }

    $finalPath = Join-Path $folder "newfile_$date.xml"
    $allData.Save($finalPath)
}

Кроме этого, не обрабатывайте XML, как если бы это был простой текст. Используйте XmlDocument.Load() и XmlDocument.Save() для чтения и записи и используйте XmlDocument.ImportNode() для передачи содержимого из одного документа в другой.

Эти две строки являются синонимами для создания XmlDocument ( документов *) 1011 *):

$xml = New-Object xml
$xml = New-Object System.Xml.XmlDocument

Это гарантирует, что входные файлы будут правильно интерпретированы для их кодировки файлов ([xml]$xml = Get-Content ... не гарантирует этого) и что сгенерированный вывод также будет правильным XML (объединяя некоторые строки и запись результата в файл не гарантирует этого).

Также рекомендуется исключить «объединенные» файлы (if ($_.Name -like "newfile*") { return }), чтобы не допустить рекурсивного добавления их друг в друга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...