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.
Leave a Reply
Want to join the discussion?Feel free to contribute!