Reputation: 3
I am quite new to PowerShell. Currently, I'm struggling with the following setup. There are several XML files contained in this folder structure:
Root |_2020-XX-XX |_file1.xml |_file2.xml |_2020-yy-yy |_file1.xml |_file2.xml
Now, I want to create a script that merges parts of each folder's xml files into one.
The result should look something like this:
|_2020-XX-XX |_file1.xml |_file2.xml |_newfile2020XXXX.xml |_2020-yy-yy |_file1.xml |_file2.xml |_newfile2020YYYY.xml
So far, my script looks like this:
$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")
While the debugger does not produce any error, the created file is
<root></root>
nodes. I can't quite figure out what to do, to troubleshoot this and would be grateful for any advice on this.
Thanks in advance for any hint!
Upvotes: 0
Views: 312
Reputation: 338336
You seem to want to create one "merged" file per folder. That means you need two loops - one for the folders, and one for the files per folder.
$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)
}
Apart from that, don't process XML as if it were plain text. Use XmlDocument.Load()
and XmlDocument.Save()
for reading and writing, and use XmlDocument.ImportNode()
to transfer content from one document to another.
These two lines are synonymous for creating an XmlDocument
(docs):
$xml = New-Object xml
$xml = New-Object System.Xml.XmlDocument
Doing so guarantees that input files are interpreted correctly for their file encoding ([xml]$xml = Get-Content ...
does not guarantee that) and that generated output is proper XML as well (concatenating some strings and writing the result to file does not guarantee that).
It's also a good idea to exclude "merged" files (if ($_.Name -like "newfile*") { return }
), so you don't end up adding them to each other recursively.
Upvotes: 1