Home > Mobile >  Powershell read XML file content in a nested zip file
Powershell read XML file content in a nested zip file

Time:07-12

I'm facing a problem related to nested zip files in powershell. Currently I have a zip file that contains a second zip file. Inside this second zip file I have a XML file that contains some business data that I need to read and access without extracting any of previous zip files. I'm able to access to the second zip but for now I can't read the XML file located in the second zip, as I'm getting it as a zipentryfile which does not offer any method to read the XML content in stream mode... Could you please provide some hint that helps me getting the required information from the XML file?

This is the hierarchy of my zip files:

OuterZip.zip--|
              |--Folder1---InnerZip.zip--|
                                         |--XMLFile.xml    // Requirement is to read content of XML file

Currently I'm able to retrieve the InnerZip.zip, but I can't read the data inside XMLFile.xml:

[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
    $zipFileContent = [IO.Compression.ZipFile]::OpenRead($file.FullName)
    $entries = $zipFileContent.Entries
    $entries | ForEach-Object {
            LogMessage -message "'$($_)'"
            LogMessage -message "'$($_.GetType())'"
            $subEntries = $_.Entries
            $subEntries | ForEach-Object {
                        LogMessage -message "'$($_)'"
                        LogMessage -message "'$($_.GetType())'"
                    }
            }

Thank you in advance

CodePudding user response:

You basically need to create a ZipArchive from the stream of the entry that is the inner ZIP.

# prefered over LoadWithPartialName
Add-Type -Assembly System.IO.Compression.Filesystem

$xmlStream = $innerArchiveStream = $innerArchive = $outerArchive = $null

try {
    # Open outer ZIP as an archive
    $outerArchive = [IO.Compression.ZipFile]::OpenRead("$PWD\OuterZip.zip")

    # Find the entry that is the inner ZIP
    $innerArchiveEntry = $outerArchive.Entries | Where-Object FullName -eq 'folder1/innerzip.zip'
    if( -not $innerArchiveEntry ) {
        throw 'Could not find innerzip.zip'
    }

    # Open inner ZIP as a stream
    $innerArchiveStream = $innerArchiveEntry.Open()
    # Create archive from the stream
    $innerArchive = [IO.Compression.ZipArchive]::new( $innerArchiveStream )

    # Find the XML file in the inner ZIP
    $xmlEntry = $innerArchive.Entries | Where-Object FullName -eq 'xmlfile.xml'
    if( -not $xmlEntry ) {
        throw 'Could not find xmlfile.xml'
    }

    # Open XML file as stream
    $xmlStream = $xmlEntry.Open()

    # Load XML document from the stream
    $xml = [xml]::new(); $xml.Load( $xmlStream )
    $xml.InnerXml   # output the XML
}
finally {
    # Cleanup
    ($xmlStream, $innerArchiveStream, $innerArchive, $outerArchive).ForEach('Dispose')
}
  • Related