XML File Validator Tool
<# .SYNOPSIS XML File Validator Tool .DESCRIPTION This script provides a tool to validate XML files, check for syntax errors, analyze the structure, and perform various XML-related tasks. .NOTES File Name : XMLValidator.ps1 Author : [Your Name] Prerequisite : PowerShell V5.1 or later Version : 1.0 Date : [Current Date] .EXAMPLE .\XMLValidator.ps1 #> Add-Type -AssemblyName System.Xml.Linq function Show-Menu { Clear-Host Write-Host "=== XML File Validator Tool ===" -ForegroundColor Cyan Write-Host "1. Validate XML File" Write-Host "2. Analyze XML Structure" Write-Host "3. Search XML" Write-Host "4. Compare Two XML Files" Write-Host "5. Validate Against XSD Schema" Write-Host "6. Exit" } function Validate-XMLFile { $filePath = Read-Host "Enter the path to the XML file" if (-not (Test-Path $filePath)) { Write-Host "File not found." -ForegroundColor Red return } try { [xml]$xml = Get-Content $filePath Write-Host "XML is valid." -ForegroundColor Green $size = (Get-Item $filePath).Length $elementCount = $xml.SelectNodes("//*").Count $attributeCount = $xml.SelectNodes("//@*").Count Write-Host "File Size: $size bytes" Write-Host "Number of Elements: $elementCount" Write-Host "Number of Attributes: $attributeCount" } catch [System.Xml.XmlException] { Write-Host "Invalid XML. Error details:" -ForegroundColor Red Write-Host $_.Exception.Message } } function Analyze-XMLStructure { $filePath = Read-Host "Enter the path to the XML file" if (-not (Test-Path $filePath)) { Write-Host "File not found." -ForegroundColor Red return } try { [xml]$xml = Get-Content $filePath $structure = Get-XMLStructure $xml.DocumentElement Write-Host "XML Structure:" -ForegroundColor Yellow $structure | ForEach-Object { Write-Host $_ } } catch { Write-Host "Error analyzing XML structure: $_" -ForegroundColor Red } } function Get-XMLStructure($element, $indent = "") { $output = @() $output += "$indent$($element.Name)" if ($element.Attributes.Count -gt 0) { $attributes = $element.Attributes | ForEach-Object { "$($_.Name)='$($_.Value)'" } $output += "$indent Attributes: $($attributes -join ', ')" } foreach ($child in $element.ChildNodes) { if ($child.NodeType -eq [System.Xml.XmlNodeType]::Element) { $output += Get-XMLStructure $child "$indent " } elseif ($child.NodeType -eq [System.Xml.XmlNodeType]::Text) { $output += "$indent Text: $($child.Value.Trim())" } } return $output } function Search-XML { $filePath = Read-Host "Enter the path to the XML file" if (-not (Test-Path $filePath)) { Write-Host "File not found." -ForegroundColor Red return } $searchTerm = Read-Host "Enter the search term (element or attribute name)" try { [xml]$xml = Get-Content $filePath $results = $xml.SelectNodes("//*[local-name()='$searchTerm'] | //@*[local-name()='$searchTerm']") if ($results.Count -eq 0) { Write-Host "No results found for: $searchTerm" -ForegroundColor Yellow } else { Write-Host "Search Results:" -ForegroundColor Green foreach ($result in $results) { Write-Host "XPath: $($result.XPath)" if ($result.NodeType -eq [System.Xml.XmlNodeType]::Element) { Write-Host "Element Value: $($result.InnerXml)" } elseif ($result.NodeType -eq [System.Xml.XmlNodeType]::Attribute) { Write-Host "Attribute Value: $($result.Value)" } Write-Host "---" } } } catch { Write-Host "Error searching XML: $_" -ForegroundColor Red } } function Compare-XMLFiles { $filePath1 = Read-Host "Enter the path to the first XML file" $filePath2 = Read-Host "Enter the path to the second XML file" if (-not (Test-Path $filePath1) -or -not (Test-Path $filePath2)) { Write-Host "One or both files not found." -ForegroundColor Red return } try { $xml1 = [System.Xml.Linq.XDocument]::Load($filePath1) $xml2 = [System.Xml.Linq.XDocument]::Load($filePath2) $differences = Compare-XmlDocs $xml1 $xml2 if ($differences.Count -eq 0) { Write-Host "The XML files are identical." -ForegroundColor Green } else { Write-Host "Differences found:" -ForegroundColor Yellow foreach ($diff in $differences) { Write-Host "XPath: $($diff.XPath)" Write-Host "File 1 Value: $($diff.Value1)" Write-Host "File 2 Value: $($diff.Value2)" Write-Host "---" } } } catch { Write-Host "Error comparing XML files: $_" -ForegroundColor Red } } function Compare-XmlDocs($doc1, $doc2) { $differences = @() $elements1 = $doc1.Descendants() $elements2 = $doc2.Descendants() foreach ($element in $elements1) { $xpath = $element.XPathSelectElement($element.GetAbsoluteXPath()) $otherElement = $doc2.XPathSelectElement($xpath.GetAbsoluteXPath()) if ($null -eq $otherElement) { $differences += @{XPath = $xpath.GetAbsoluteXPath(); Value1 = $element.Value; Value2 = "Element not found"} } elseif ($element.Value -ne $otherElement.Value) { $differences += @{XPath = $xpath.GetAbsoluteXPath(); Value1 = $element.Value; Value2 = $otherElement.Value} } foreach ($attr in $element.Attributes()) { $otherAttr = $otherElement?.Attribute($attr.Name) if ($null -eq $otherAttr) { $differences += @{XPath = "$($xpath.GetAbsoluteXPath())/@$($attr.Name)"; Value1 = $attr.Value; Value2 = "Attribute not found"} } elseif ($attr.Value -ne $otherAttr.Value) { $differences += @{XPath = "$($xpath.GetAbsoluteXPath())/@$($attr.Name)"; Value1 = $attr.Value; Value2 = $otherAttr.Value} } } } foreach ($element in $elements2) { $xpath = $element.XPathSelectElement($element.GetAbsoluteXPath()) $otherElement = $doc1.XPathSelectElement($xpath.GetAbsoluteXPath()) if ($null -eq $otherElement) { $differences += @{XPath = $xpath.GetAbsoluteXPath(); Value1 = "Element not found"; Value2 = $element.Value} } foreach ($attr in $element.Attributes()) { $otherAttr = $otherElement?.Attribute($attr.Name) if ($null -eq $otherAttr) { $differences += @{XPath = "$($xpath.GetAbsoluteXPath())/@$($attr.Name)"; Value1 = "Attribute not found"; Value2 = $attr.Value} } } } return $differences } function Validate-XMLAgainstXSD { $xmlPath = Read-Host "Enter the path to the XML file" $xsdPath = Read-Host "Enter the path to the XSD schema file" if (-not (Test-Path $xmlPath) -or -not (Test-Path $xsdPath)) { Write-Host "One or both files not found." -ForegroundColor Red return } try { $xmlReader = [System.Xml.XmlReader]::Create($xmlPath) $schemaReader = [System.Xml.XmlReader]::Create($xsdPath) $schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $null) $settings = New-Object System.Xml.XmlReaderSettings $settings.ValidationType = [System.Xml.ValidationType]::Schema $settings.Schemas.Add($schema) | Out-Null $settings.ValidationEventHandler = { param($sender, $e) Write-Host "Validation Error: $($e.Message)" -ForegroundColor Red } $validatingReader = [System.Xml.XmlReader]::Create($xmlPath, $settings) while ($validatingReader.Read()) { } Write-Host "XML is valid according to the XSD schema." -ForegroundColor Green } catch { Write-Host "Error validating XML against XSD: $_" -ForegroundColor Red } finally { if ($null -ne $xmlReader) { $xmlReader.Close() } if ($null -ne $schemaReader) { $schemaReader.Close() } if ($null -ne $validatingReader) { $validatingReader.Close() } } } # Extension method to get absolute XPath Add-Type @" using System.Xml.Linq; using System.Linq; public static class XElementExtensions { public static string GetAbsoluteXPath(this XElement element) { if (element == null) return string.Empty; var ancestors = element.AncestorsAndSelf().Reverse().ToList(); return "/" + string.Join("/", ancestors.Select(e => e.Name.LocalName)); } } "@ # Main program loop do { Show-Menu $choice = Read-Host "`nEnter your choice (1-6)" switch ($choice) { "1" { Validate-XMLFile } "2" { Analyze-XMLStructure } "3" { Search-XML } "4" { Compare-XMLFiles } "5" { Validate-XMLAgainstXSD } "6" { Write-Host "Exiting program..." -ForegroundColor Yellow; break } default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red } } if ($choice -ne "6") { Read-Host "`nPress Enter to continue..." } } while ($choice -ne "6")
This XML File Validator Tool includes:
- A menu-driven interface for easy navigation.
- Functions to perform various XML-related tasks:
- Validate XML files and provide basic statistics
- Analyze and display the structure of XML files
- Search for specific elements or attributes within XML files
- Compare two XML files and highlight differences
- Validate XML against an XSD schema
Key features:
- XML Validation:
- Checks if the XML is syntactically valid
- Provides file size, number of elements, and number of attributes
- XML Structure Analysis:
- Displays a hierarchical view of the XML structure
- Shows element names, attributes, and text content
- XML Search:
- Allows searching for specific elements or attributes within the XML
- Displays the XPath and value of found elements/attributes
- XML Comparison:
- Compares two XML files
- Highlights differences, including added, removed, or modified elements and attributes
- XSD Schema Validation:
- Validates an XML file against an XSD schema
- Reports any validation errors
This tool is particularly useful for:
- Developers working with XML data
- QA engineers validating XML outputs
- Data analysts examining XML structures
- Anyone needing to quickly validate, analyze, or compare XML files
To use this script effectively:
- Run the script in PowerShell
- Use the menu options to select the desired function
- Provide the path to the XML file(s) when prompted
- Review the output for validation results, structure analysis, search results, file comparisons, or schema validation
This script provides a comprehensive set of tools for working with XML files, making it easier to validate, understand, and compare XML data without having to manually parse the files or use multiple tools.