Netz-Weise Logo

Weisheiten - der Netz-Weise Blog

Hier finden Sie Tipps und Tricks für vor, während und nach der Schulung.
3 Minuten Lesezeit (524 Worte)

Zwei XML-Dateien mit Powershell vergleichen und einen HTML-Report erzeugen

Das XML-Format ist allgegenwärtig. Als Windows-Administrator stolpert man regelmäßig über Eventlogs im XML-Format, Anweisungsdateien für die unbeaufsichtigte Installation, Vorlagen für Gruppenrichtlinien usw. Und manchmal wäre es ganz schön, wenn man sich den Unterschied zwischen zwei ähnlichen XML-Dateien einfach anzeigen lassen könnte. Mit Powershell und ein bißchen .net ist das in der Tag auch gar kein Problem, denn Microsoft hat vor fast 15 Jahren eine .Net-Bibliothek zur Verfügung gestellt, die genau das tut - das XML Diff & Patch GUI Tool. Das Tool stellt eine Klasse zur Verfügung, über die es möglich ist, zwei XML-Dateien zu vergleichen und die Unterschiede in der XML DIfference Language (Diffgram) auszugeben. Mit einer weiteren Klasse kann man aus einer Diffgram-Datei und einer der beiden Vergleichsdateien eine HTML-Datei erzeugen, die die Unterschiede grafisch darstellt.

So sieht ein HTML Vergleich aus

Wenn Sie die heruntergeladene Bibliothek entpacken, finden Sie im zwei .dlls, die Sie laden müssen, die XmlDiffPath.dll, die die Compare()-Methode zur Verfügung stellt, und die XmlDiffPath.View.dll, die die Methode GetHtml() bereitstellt. GetHtml erstellt aus einer Diffgram-Datei eine HTML-Datei. Laden Sie die Klassen und erstellen Sie zwei neue Objekte.

Add-Type -Path "xmldiffpatch.dll"
$XmlDiff = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiff
Add-Type -Path "XmlDiffPatch.View.dll"
$XmlDiffView = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiffView

Anschließend können Sie die Methode Compare() aufrufen. Compare hat eine Reihe von Überladungen (verschiedene Parameter-Kombinationen). Zum Erstellen eines Diffgramwriters benötigen Sie die beiden zu vergleichenden XML-Dateien, $false und einen .Net-Streamwriter zum Schreiben der Diffgram-Datei:

$DiffGramWriter = [System.Xml.XmlWriter]::Create( 'C:\temp\Diffgram.xml' )
#call Compare method from Microsoft.XmlDiffPatch.XmlDiff object
$XmlDiff.Compare('C:\temp\File1.xml','C:\Temp\File2.xml',$false,$DiffGramWriter)
$DiffGramWriter.Close()

Anschließend erstellen Sie mit Hilfe der Methode GetHtml() die Ausgabedatei. GetHTML() benötigt als Parameter nur einen Streamwriter für die Ausgabe, allerdings müssen vorher mit Load() eine der beiden Vergleichsdateien und die generierte Diffgram-Datei in die Klasse geladen werden.

# Laden der Dateien mit Hilfe von Streamreadern:
$Orig = [System.Xml.XmlTextReader]::Create('C:\Temp\File1.xml')
$DiffGram = [System.Xml.XmlTextReader]::Create('C:\temp\Diffgram.xml')
$StreamWriter = New-object -TypeName System.IO.StreamWriter -ArgumentList 'C:\Temp\Result.html'
$XmlDiffView.Load($Orig,$DiffGram)

# Schreiben der Differenz-Datei
$XmlDiffView.GetHtml($StreamWriter)
$StreamWriter.Close()
$Orig.Close()
$DiffGram.Close() 

Da das ganze nicht besonders gut formatiert ist, kann man noch einen HTML-Header und Footer einfügen. Der einfachheit halber habe ich gleich eine Funktion aus dem Code gebaut. Sie müssen dann allerdings den Pfad zu den Bibliotheken anpassen. Alternativ laden Sie die Funktion einfach direkt als Modul herunter.

Function Compare-XML
{
  param(
    [String]$XmlFile1,
    [String]$XmlFile2,
    [string]$ResultFile,
    [string]$DiffDataGramPath = ( "$env:TEMP\DataDiff.xml" )
  )
 
  Add-Type -Path "$PSScriptRoot\xmlDiff\xmldiffpatch.dll"
  $XmlDiff = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiff
  Add-Type -Path "$PsScriptroot\xmlDiff\XmlDiffPatch.View.dll"
  $XmlDiffView = New-Object -TypeName Microsoft.XmlDiffPatch.XmlDiffView
 
  $HtmlHeader = @"
<html><body>
<p><b>Legend:</b>
<font style='background-color: yellow' color='black'> added</font>
&nbsp;&nbsp;<font style='background-color:red' color='black'>removed</font>
&nbsp;&nbsp;<font style='background-color:lightgreen' color='black'>changed</font>&nbsp;&nbsp;
<font style='background-color: red' color='blue'>moved from</font>
&nbsp;&nbsp;<font style='background-color: yellow' color='blue'>moved to</font>&nbsp;&nbsp;
<font style='background-color: white' color='#AAAAAA'>ignored</font>
</p>
<table width='100%'>
<tr><td colspan='2' align='center'>
"@

  $HtmlFooter = @"
</table></body></html>
"@
 
  #create XmlWriter object with path where to create the resulting XML file
  $DiffGramWriter = [System.Xml.XmlWriter]::Create( $DiffDataGramPath )
  #call Compare method from Microsoft.XmlDiffPatch.XmlDiff object
  $XmlDiff.Compare($XmlFile1,$XmlFile2,$false,$DiffGramWriter)
  $DiffGramWriter.Close()
 
  $Orig = [System.Xml.XmlTextReader]::Create($XmlFile1)
  $DiffGram = [System.Xml.XmlTextReader]::Create($DiffDataGramPath)
  $StreamWriter = New-object -TypeName System.IO.StreamWriter -ArgumentList $ResultFile
  $XmlDiffView.Load($Orig,$DiffGram)
 
  $StreamWriter.Write($htmlHeader)
  $XmlDiffView.GetHtml($StreamWriter)
  $StreamWriter.Write($HtmlFooter)
  $StreamWriter.Close()
  $Orig.Close()
  $DiffGram.Close()  
}

Das XML Diff-und Patch GUI Tool kann übrigens noch mehr, wie z.B. XML-Dateien synchronisieren.

Links

Compare and Patch XML-Documents

Mit Powershell ein Kennwort gegen AD prüfen
USB-Geräte mit Powershell und WMI auslesen

Ähnliche Beiträge

 

Kommentare 1

Gäste - Peter Monadjemi am Freitag, 07. Mai 2021 11:24

Hallo Holger,

Ich habe das Tool leider nicht gefunden - die Links in dem Artikel scheinen nicht mehr zu funktionieren. Es gibt ein Nuget-Package mit den beiden Assemblies, aber offenbart basiert die Assembly noch auf .NET 1.0, so dass ich sie nicht per PowerShell laden konnte:

https://www.nuget.org/packages/XMLDiffPatch/

Ich hätte Dein Skript gerne einmal getestet, da ich den HTML-Output mit dem Hervorheben der Unterschiede sehr praktisch finde, aber mit der Assembly ist das wohl nicht möglich.

Viele Grüße,
Peter


Hallo Holger, Ich habe das Tool leider nicht gefunden - die Links in dem Artikel scheinen nicht mehr zu funktionieren. Es gibt ein Nuget-Package mit den beiden Assemblies, aber offenbart basiert die Assembly noch auf .NET 1.0, so dass ich sie nicht per PowerShell laden konnte: https://www.nuget.org/packages/XMLDiffPatch/ Ich hätte Dein Skript gerne einmal getestet, da ich den HTML-Output mit dem Hervorheben der Unterschiede sehr praktisch finde, aber mit der Assembly ist das wohl nicht möglich. Viele Grüße, Peter
Bereits registriert? Hier einloggen
Sonntag, 19. Mai 2024

Sicherheitscode (Captcha)