importXmlToSql.psm1
Import-Module SqlServer $Global:valueStrings = "values(" $Global:columnsString ="insert into $TableName(" <# .Synopsis DImport an xml to sql table .Description Import xml to sql table .Parameter SqlServer Sql server instance .Parameter DatabaseName Database name .Parameter Username Username for sql server instance. If this value is null, we consider as being Integrated Security = true .Parameter Password Password for sql server instance. .Parameter ConnectionString ConnectionString to sql server. .Parameter XmlFile Path to xml that has to be imported .Parameter Mapping A hashtable that contains the mapping of node/attribute to column table. The form of this table should be: 'pathToNode'='columnName' .Example Map a xml node inner text to a column named column1 Xml: <a> <b> <c>Test</c> </b> </a> Import-XmlToSql -ConnectionString "connectionString" -XmlFile "xmlFilePath" -Mapping @{"a.b.c"="Column1"} .Example Map a xml node attribute attr to a column named column2 Xml: <a> <b attr="aa"> <c>Test</c> </b> </a> Import-XmlToSql -ConnectionString "connectionString" -XmlFile "xmlFilePath" -Mapping @{"a.b[attr]"="Column2"} #> Function Import-XmlToSql { param ( [Parameter(Mandatory=$true,ParameterSetName="sql")] [ValidateNotNullOrEmpty()] [string] $SqlServer, [Parameter(Mandatory=$true,ParameterSetName="sql")] [ValidateNotNullOrEmpty()] [string] $DatabaseName, [Parameter(Mandatory=$false,ParameterSetName="sql")] [ValidateNotNullOrEmpty()] [string] $Username, [Parameter(Mandatory=$false,ParameterSetName="sql")] [ValidateNotNullOrEmpty()] [securestring] $Password, [Parameter(Mandatory=$true,ParameterSetName="connectionString")] [ValidateNotNullOrEmpty()] [string] $ConnectionString, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $TableName, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $XmlFile, [Parameter(Mandatory=$true)] [hashtable] $Mapping ) $xmldocument = New-Object System.xml.XmlDocument $xmlDocument.Load($XmlFile) if([string]::IsNullOrWhiteSpace($ConnectionString) -eq $true) { $ConnectionString = Get-ConnectionString -SqlServer $SqlServer -DatabaseName $DatabaseName -Username $Username -Password $Password } $result = Invoke-Sqlcmd -ConnectionString $ConnectionString -Query "SELECT COUNT(*) AS Count FROM $TableName" -As DataRows if($result -ne $null) { foreach($xmlNode in $xmldocument.root.ChildNodes) { $Global:valueStrings = "values(" $Global:columnsString ="insert into $TableName(" Execute-Command -XmlNode $xmlNode -Mapping $Mapping $Global:valueStrings=$Global:valueStrings+")" $Global:columnsString=$Global:columnsString+")" $sqlStatement = $columnsString+$valueStrings if($sqlStatement -ne "insert into $TableName()values()") { Invoke-Sqlcmd -ConnectionString $ConnectionString -Query $sqlStatement -OutputAs DataRows } } } } Function Get-ConnectionString { param ( [string] $SqlServer, [string] $DatabaseName, [string] $Username, [securestring] $Password ) $connectionBuilder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder $connectionBuilder["Data Source"] = $SqlServer $connectionBuilder["Initial Catalog"] = $DatabaseName if([string]::IsNullOrWhiteSpace($Username) -ne $true) { $connectionBuilder["User ID"] = $Username $psCredentials = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $password $connectionBuilder["Password"] = $psCredentials.GetNetworkCredential().Password } else { $connectionBuilder["integrated Security"] = $true; } return $($connectionBuilder.ConnectionString) } Function Get-NodePath { param ( [System.Xml.XmlNode] $XmlNode ) $localXmlNode = $XmlNode.CloneNode($true) $stringBuilder = New-Object System.Text.StringBuilder if($localXmlNode.Attributes -ne $null) { $localXmlNode.Attributes.RemoveAll() } $result = [string]::Format("{0}",$localXmlNode.Name) $XmlNode = $XmlNode.ParentNode while($XmlNode -ne $null) { $localXmlNode = $XmlNode.CloneNode($true) if($localXmlNode.Attributes -ne $null) { $localXmlNode.Attributes.RemoveAll() } if($localXmlNode.Name.Contains("#") -eq $false) { $result = [string]::Format("{0}.{1}",$localXmlNode.Name,$result) } $XmlNode = $XmlNode.ParentNode } $localXmlNode = $localXmlNode return $result } Function Get-NodeValue { param ( [string] $Key, [System.Xml.XmlNode] $XmlNode ) if($Key.Contains("[")) { $attribute = $Key.Split("[")[1] $attribute = $attribute.TrimEnd("]").TrimStart("[") return $($XmlNode.Attributes[$attribute].Value) } return $($XmlNode.InnerText) } Function Find-Key { param ( [string] $XmlNodePath, [System.Collections.Generic.List[string]] $Keys ) $result = New-Object System.Collections.Generic.LinkedList[string] foreach($key in $Keys) { if($key.Split("[")[0].Equals($XmlNodePath) -eq $true) { $result.AddFirst($key) | Out-Null } } return $result } Function Execute-Command { param ( [System.Xml.XmlNode] $XmlNode, [hashtable] $Mapping ) Process-XmlNode -XmlNode $XmlNode -Mapping $Mapping foreach($xmlNode in $XmlNode.ChildNodes) { Execute-Command -XmlNode $XmlNode -Mapping $Mapping | Out-Null } } Function Process-XmlNode { param ( [System.Xml.XmlNode] $XmlNode, [hashtable] $Mapping ) $nodePath = Get-NodePath -XmlNode $XmlNode $keyList = Find-Key -XmlNodePath $nodePath -Keys $Mapping.Keys foreach($key in $keyList) { $value = Get-NodeValue -Key $key -XmlNode $XmlNode if($value -ne $null) { if($Global:valueStrings.EndsWith("(") -eq $true) { $Global:valueStrings=$Global:valueStrings+"'"+$value.Replace("'","''")+"'" $Global:columnsString = $Global:columnsString+$Mapping[$key] } else { $Global:valueStrings=$Global:valueStrings+","+"'"+$value.Replace("'","''")+"'" $Global:columnsString = $Global:columnsString+","+$Mapping[$key] } } } } Export-ModuleMember -Function Import-XmlToSql |