Tipps

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


 335,    17  Jan  2019 ,   Tipp
Holger Voges

  E-Mail Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!

Holger Voges ist Inhaber der Firma Netz-Weise IT-Training und seit 1999 als Trainer und Consultant tätig. Als Allrounder in den Bereichen Windows Server, Active Directory, SQL Server, Hyper-V und Windows PowerShell, hat er in der Vergangenheit zahlreiche Einsätze als Consultant in namenhaften Firmen absolviert und so neben der Theorie auch umfangreiche praktische Erfahrungen gesammelt.

 

Netz-Weise

Das Haupt-Tätigkeitsfeld von Netz-Weise sind Schulungen für Profis. Bei uns bekommen Sie das Programm für den fortgeschrittenen Praktiker, der die Tiefen des Systems ausloten möchte genauso wie Standard-Schulungen.

So erreichen Sie uns:

Netz-Weise
IT-Training und Beratung
Freundallee 13a
30173 Hannover
 
Tel: (0511) 165 925-0
Fax: (0511) 165 925-99
email: info(at)netz-weise.de
 

Newsletter bestellen

Das Wichtigste kompakt ins E-Mailfach!