cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Splitting exported XML into separate objects

Splitting exported XML into separate objects

Objects' XML representations can be extracted from IdentityIQ through the IIQ console using the export and checkout commands. The export command writes all objects of one or more types to a single XML file. The checkout command writes a single named object to an XML file.

Frequently, customers want to get all objects of a given type out of the system at once but need them all in separate files (e.g. to store them separately in a source code repository). Though there is no built in console command that does bulk exports into separate files, the attached Perl script can take the output from an export command and parse it into separate files per object.

How to use this script:

  1. Download the script to the filesystem where IdentityIQ is installed.
  2. Use the export command to export all objects of a given type from the console. Note: This script only parses export files that were created with the -clean option  (ID values stripped).
    • > export -clean /home/spadmin/artifacts/workflows.xml workflow
  3. Run this script, providing the export filename and the target directory name. (When no target directory is specified, split files will be written to a subdirectory of the current directory called splitOut.)
    • $ ./splitXml.pl /home/spadmin/artifacts/workflows.xml splitWorkflows
    • (This creates separate files for each workflow in a subdirectory of the current directory called splitWorkflows.)
Labels (1)
Attachments
Comments

We could not install Perl at customer servers to run the script, so I converted it to PowerShell, tested it out, and it works 1:1. 

For those interested here is the script, save it as splitxml.ps1:

# SailPoint XML Object Splitting Utility
Write-Host "SailPoint XML Object Splitting Utility."

$inFile = $args[0]

if (!$inFile) {
Write-Host "Usage: script.ps1 [SailPoint-Export-Name.xml] [splitOutDir]"
Write-Host " If no splitOutDir named, creates a sub-directory called 'splitOut' for output."
Write-Host " Objects should be exported with the -clean option (no ID values)."
exit
}

$outDir = "./splitOut"
if ($args[1]) {
$outDir = $args[1]
}
if (!(Test-Path $outDir)) {
New-Item -ItemType Directory -Path $outDir -ErrorAction Stop | Out-Null
}

$xmlHeader = ''
$lineNumber = 0
$line4spacesFlag = 0
$skipRecord = 0

Get-Content $inFile | ForEach-Object {
$lineNumber++
$thisLine = $_ -replace "`r", "" -replace "`n", ""

if ($lineNumber -eq 4 -and $thisLine.StartsWith(" ")) {
$line4spacesFlag = 1
}

if ($lineNumber -le 3) {
$xmlHeader += $thisLine + "`n"
} else {
if ($thisLine -match 'id="') {
Write-Host "Warning: 'id=' found in the XML, did you export with '-clean'?"
}

if ($line4spacesFlag -eq 1) {
$baseObjStartRegex = '^ <(\S+)\s+'
} else {
$baseObjStartRegex = '^<(\S+)\s+'
}

if ($thisLine -match $baseObjStartRegex) {
$objType = $matches[1]
Write-Host " - Found Object Type: $objType"

if ($line4spacesFlag -eq 1) {
$baseObjEndRegex = "^ </$objType>"
} else {
$baseObjEndRegex = "^</$objType>"
}

if ($thisLine -match "^<$objType.*?name=""([^""]+)""") {
$objectName = $matches[1]
$objectNameHy = $objectName -replace "/", "-" -replace "\\", "-" -replace " - ", "-" -replace "&amp;", "and" -replace "&apos;", "-" -replace " ", "-" -replace ":", "-"
 
$outFileName = Join-Path $outDir "$($objType)-$($objectNameHy).xml"
Write-Host " - file name: $outFileName"
 
Set-Content $outFileName $xmlHeader
Add-Content $outFileName $thisLine
} elseif ($objType -eq 'JasperResult' -or $objType -eq 'Request') {
Write-Host " - Skipping object of type $objType."
$skipRecord = 1
} else {
Write-Host "ERROR: unexpected line: [$thisLine]"
throw "ERROR: Something is broken in the XML input."
}
} elseif ($thisLine -match $baseObjEndRegex) {
if ($skipRecord -eq 0) {
Add-Content $outFileName $thisLine
Add-Content $outFileName "</sailpoint>"
} else {
$skipRecord = 0
}
} else {
if ($skipRecord -eq 0) {
Add-Content $outFileName $thisLine
}
}
}
}
Write-Host "nXML Split out operation complete.n"
#FINISHED
 
 
For the commands to initiate this one, I created a second PowerShell script to call the one above with the commands (good when you need to export and compare baseline to production differences where exports are at different locations:
 
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
Set-Location -Path "D:\TEMP\exports\PROD" #CHANGE LOCATION TO WHERE THE FILES ARE LOCATED (exports from main script + splitxml.ps1)
.\splitxml.ps1 CurrentApplicationExported.xml Application.\splitxml.ps1 CurrentAuditConfigExported.xml AuditConfig
 
Maybe someone else is in the same need, so no need to waste time converting it. Have fun!
Version history
Revision #:
2 of 2
Last update:
‎Jul 25, 2023 06:54 PM
Updated by: