none
Mit Powershell xml File auslesen und in ein csv schreiben RRS feed

  • Frage

  • Hallo Forum

    Ich bin nun schon seit einigen Stunden am versuchen, dieses xml File auszulesen und in eine csv Liste zu schreiben. Leider gelingt mir dies noch nicht wie gewünscht und ich hoffe jemand von euch kann mir dieses Rätsel lösen. :-)

    Das XML-File hat folgende Struktur:

    <?xml version="1.0" encoding="utf-8"?>
    <VMSystem xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <VersionConfig>6.0.0.5</VersionConfig>
      <Filename>XMLConf.xml</Filename>
      <Compatibilty>VMSystem</Compatibilty>
      <Management>
        <ManagementName>Basel</ManagementName>
      </Management>
      <DeviceServerList>
        <DeviceServerCnf>
          <DeviceServerName>bs-lsm-001</DeviceServerName>
          <VideoDeviceList>
            <VideoDevice>
              <VideoDeviceHostName>bs-enc-001</VideoDeviceHostName>
              <VideoDeviceCameraList>
                <Camera>
                  <CameraUID>1900001</CameraUID>              
                </Camera>
              </VideoDeviceCameraList>
            </VideoDevice>
            <VideoDevice>
              <VideoDeviceHostName>bs-enc-002</VideoDeviceHostName>
              <VideoDeviceCameraList>
                <Camera>
                  <CameraUID>1900002</CameraUID>
                </Camera>
              </VideoDeviceCameraList>
            </VideoDevice>
    		<VideoDevice>
              <VideoDeviceHostName>kau-cam-003</VideoDeviceHostName>
              <VideoDeviceCameraList>
                <Camera>
                  <CameraUID>1900149</CameraUID>
                </Camera>
              </VideoDeviceCameraList>
            </VideoDevice>
          </VideoDeviceList>
        </DeviceServerCnf>
        <DeviceServerCnf>
          <DeviceServerName>bs-dvs-001</DeviceServerName>
          <VideoDeviceList>
            <VideoDevice>
              <VideoDeviceHostName>bsja-enc-006</VideoDeviceHostName>
              <VideoDeviceCameraList>
                <Camera>
                  <CameraUID>1900115</CameraUID>
                </Camera>
              </VideoDeviceCameraList>
            </VideoDevice>
            <VideoDevice>
              <VideoDeviceHostName>bsja-enc-005</VideoDeviceHostName>
              <VideoDeviceCameraList>
                <Camera>
                  <CameraUID>1900114</CameraUID>
                </Camera>
              </VideoDeviceCameraList>
            </VideoDevice>
          </VideoDeviceList>
        </DeviceServerCnf> 
      </DeviceServerList>
    </VMSystem>

    Am Schluss möchte ich eine Liste, welche folgendermassen aussieht:

    Standort     DeviceServerName     CameraID     CameraHostname 

    Basel          bs-lsm-001                 1900001      bs-enc-001
    Basel          bs-lsm-001                 1900002      bs-enc-002
    Basel          bs-lsm-001                 1900149      kau-cam-003
    Basel          bs-dvs-001                 1900115      bsja-enc-006

    Versucht habe ich es mit diesem Code, jedoch kriege ich die Verlinkung der CameraID und dem CameraHostName nicht hin.

    $DestinationDirectory = "\\zol-dc-01\Daten\Backups\Massenexport"
    $Files = Get-ChildItem -Path $DestinationDirectory -Filter *.xml
    foreach ($File in $Files)
    {
        $a=([xml](gc $DestinationDirectory\$File)).VMSystem
        $d=([xml](gc $DestinationDirectory\$File)).VMSystem.DeviceServerList.DeviceServerCnf | % { 
          foreach ($i in $_.VideoDeviceList.VideoDevice.VideoDeviceCameraList.Camera.CameraUID) 
          {
            $o = New-Object Object
            Add-Member -InputObject $o -MemberType NoteProperty -Name Standort -Value $a.Management.ManagementName
            Add-Member -InputObject $o -MemberType NoteProperty -Name DeviceServerName -Value $_.DeviceServerName
            Add-Member -InputObject $o -MemberType NoteProperty -Name CameraID -Value $i
    
            foreach ($j in $_.VideoDeviceList.VideoDevice.VideoDeviceHostName) 
            {
                Add-Member -InputObject $o -MemberType NoteProperty -Name CameraHostname -Value $_.VideoDeviceList.VideoDevice.VideoDeviceHostName -Force | Where-Object {$i -eq  ($_.VideoDeviceList.VideoDevice.VideoDeviceCameraList.Camera.CameraUID)}
            }
        
            $o
    
          }
        }
        $d
        #$d | Export-Csv -NoTypeInformation -Path "$DestinationDirectory\$File.csv"

    Ich habe im Beispiel nun lediglich ein xml File erwähnt. Am Schluss habe ich ca. 16 xml Files, welche ich nach diesem Verfahren durchsuchen und eine csv Liste erstellen möchte. Dies nur zur Erklärung.

    Danke für eure Hilfe oder Tipps.
    Gruss Thomas

    Dienstag, 17. Januar 2017 11:06

Antworten

  • Puh ... das war ein bissl kniffelig irgendwie ... aber ich denke, ich bin ziemlich dicht dran, oder? ;-)
    $XMLRootPath = '\\zol-dc-01\Daten\Backups\Massenexport'
    $XMLFiles = Get-ChildItem -Path  $XMLRootPath -Filter '*.xml' -File | Select-Object -ExpandProperty FullName
    
    Foreach($XMLFile in $XMLFiles){
        [XML]$xml = Get-Content $XMLFile
        $Standort = $xml.vmsystem.Management | Select-Object -ExpandProperty ManagementName
    
        $DeviceServerNames = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Select-Object -ExpandProperty DeviceServerName 
        Foreach($DeviceServerName in $DeviceServerNames){
            $VideoDeviceHostNames = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ |  Select-Object -ExpandProperty VideoDeviceList |  Select-Object -ExpandProperty  VideoDevice |  Select-Object -ExpandProperty VideoDeviceHostName
            foreach ($VideoDeviceHostName in $VideoDeviceHostNames) {
                $CameraUIDs = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ |  Select-Object -ExpandProperty VideoDeviceList |  Select-Object -ExpandProperty  VideoDevice |  Where-Object -Property 'VideoDeviceHostName' -Value $VideoDeviceHostName -EQ | Select-Object -ExpandProperty VideoDeviceCameraList | Select-Object -ExpandProperty Camera | Select-Object -ExpandProperty CameraUID
                foreach ($CameraUID in $CameraUIDs) {
                    [PSCustomObject]@{
                        Standort = $Standort
                        DeviceServerName = $DeviceServerName
                        VideoDeviceHostName = $VideoDeviceHostName
                        CameraUID =  $CameraUID
                    }
                }
            }
        }
    }
    Ich weiß nicht, ob es noch einen eleganteren oder kürzeren Weg gibt, aber für'n Anfang sollte es reichen.

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Bearbeitet BOfH-666 Dienstag, 17. Januar 2017 21:00 Tippfehler korrigiert
    • Als Antwort markiert Idefixli Donnerstag, 19. Januar 2017 14:11
    Dienstag, 17. Januar 2017 20:59
  • OK, man kann die sehr langen Zeilen noch ein bissl einkürzen:

    $XMLRootPath = '\\zol-dc-01\Daten\Backups\Massenexport'
    $XMLFiles = Get-ChildItem -Path  $XMLRootPath -Filter '*.xml' -File | Select-Object -ExpandProperty FullName
    
    Foreach($XMLFile in $XMLFiles){
        [XML]$xml = Get-Content $XMLFile
        $Standort = ($xml.vmsystem.Management).ManagementName
    
        $DeviceServerNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf).DeviceServerName
        Foreach($DeviceServerName in $DeviceServerNames){
            $VideoDeviceHostNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice.VideoDeviceHostName
            foreach ($VideoDeviceHostName in $VideoDeviceHostNames) {
                $CameraUIDs = (($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice |  Where-Object -Property 'VideoDeviceHostName' -Value $VideoDeviceHostName -EQ ).VideoDeviceCameraList.Camera.CameraUID
                foreach ($CameraUID in $CameraUIDs) {
                    [PSCustomObject]@{
                        Standort = $Standort
                        DeviceServerName = $DeviceServerName
                        VideoDeviceHostName = $VideoDeviceHostName
                        CameraUID =  $CameraUID
                    }
                }
            }
        }
    }
    


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Dienstag, 17. Januar 2017 21:09

Alle Antworten

  • es gibt auch ein eigenes CmdLet dafür

    $Data2 = Import-Clixml Data.xml


    Chris

    Dienstag, 17. Januar 2017 16:10
  • Hmmm .... nee sorry ... ich denke nicht.  ;-)

    Das cmdlet Import-Clixml ist dafür gemacht um per Export-Clixml exportierte serialisierte Ausgabeopbjecte von cmdlets wieder einzulesen. 

    Ich finde das Free Powershell Cookbook XML immer sehr empfehlenswert. Schau mal! :-)


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Dienstag, 17. Januar 2017 16:38
  • Puh ... das war ein bissl kniffelig irgendwie ... aber ich denke, ich bin ziemlich dicht dran, oder? ;-)
    $XMLRootPath = '\\zol-dc-01\Daten\Backups\Massenexport'
    $XMLFiles = Get-ChildItem -Path  $XMLRootPath -Filter '*.xml' -File | Select-Object -ExpandProperty FullName
    
    Foreach($XMLFile in $XMLFiles){
        [XML]$xml = Get-Content $XMLFile
        $Standort = $xml.vmsystem.Management | Select-Object -ExpandProperty ManagementName
    
        $DeviceServerNames = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Select-Object -ExpandProperty DeviceServerName 
        Foreach($DeviceServerName in $DeviceServerNames){
            $VideoDeviceHostNames = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ |  Select-Object -ExpandProperty VideoDeviceList |  Select-Object -ExpandProperty  VideoDevice |  Select-Object -ExpandProperty VideoDeviceHostName
            foreach ($VideoDeviceHostName in $VideoDeviceHostNames) {
                $CameraUIDs = $xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ |  Select-Object -ExpandProperty VideoDeviceList |  Select-Object -ExpandProperty  VideoDevice |  Where-Object -Property 'VideoDeviceHostName' -Value $VideoDeviceHostName -EQ | Select-Object -ExpandProperty VideoDeviceCameraList | Select-Object -ExpandProperty Camera | Select-Object -ExpandProperty CameraUID
                foreach ($CameraUID in $CameraUIDs) {
                    [PSCustomObject]@{
                        Standort = $Standort
                        DeviceServerName = $DeviceServerName
                        VideoDeviceHostName = $VideoDeviceHostName
                        CameraUID =  $CameraUID
                    }
                }
            }
        }
    }
    Ich weiß nicht, ob es noch einen eleganteren oder kürzeren Weg gibt, aber für'n Anfang sollte es reichen.

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''


    • Bearbeitet BOfH-666 Dienstag, 17. Januar 2017 21:00 Tippfehler korrigiert
    • Als Antwort markiert Idefixli Donnerstag, 19. Januar 2017 14:11
    Dienstag, 17. Januar 2017 20:59
  • OK, man kann die sehr langen Zeilen noch ein bissl einkürzen:

    $XMLRootPath = '\\zol-dc-01\Daten\Backups\Massenexport'
    $XMLFiles = Get-ChildItem -Path  $XMLRootPath -Filter '*.xml' -File | Select-Object -ExpandProperty FullName
    
    Foreach($XMLFile in $XMLFiles){
        [XML]$xml = Get-Content $XMLFile
        $Standort = ($xml.vmsystem.Management).ManagementName
    
        $DeviceServerNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf).DeviceServerName
        Foreach($DeviceServerName in $DeviceServerNames){
            $VideoDeviceHostNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice.VideoDeviceHostName
            foreach ($VideoDeviceHostName in $VideoDeviceHostNames) {
                $CameraUIDs = (($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice |  Where-Object -Property 'VideoDeviceHostName' -Value $VideoDeviceHostName -EQ ).VideoDeviceCameraList.Camera.CameraUID
                foreach ($CameraUID in $CameraUIDs) {
                    [PSCustomObject]@{
                        Standort = $Standort
                        DeviceServerName = $DeviceServerName
                        VideoDeviceHostName = $VideoDeviceHostName
                        CameraUID =  $CameraUID
                    }
                }
            }
        }
    }
    


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Dienstag, 17. Januar 2017 21:09
  • komisch, dass es für XML noch keine besseren  CmdLets gibt.


    Chris

    Mittwoch, 18. Januar 2017 06:42
  • Sie sind noch nicht dazu gekommen ...  zu viel zu tun.  :-D

    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Mittwoch, 18. Januar 2017 07:58
  • OK, man kann die sehr langen Zeilen noch ein bissl einkürzen:

    $XMLRootPath = '\\zol-dc-01\Daten\Backups\Massenexport'
    $XMLFiles = Get-ChildItem -Path  $XMLRootPath -Filter '*.xml' -File | Select-Object -ExpandProperty FullName
    
    Foreach($XMLFile in $XMLFiles){
        [XML]$xml = Get-Content $XMLFile
        $Standort = ($xml.vmsystem.Management).ManagementName
    
        $DeviceServerNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf).DeviceServerName
        Foreach($DeviceServerName in $DeviceServerNames){
            $VideoDeviceHostNames = ($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice.VideoDeviceHostName
            foreach ($VideoDeviceHostName in $VideoDeviceHostNames) {
                $CameraUIDs = (($xml.vmsystem.DeviceServerList.DeviceServerCnf | Where-Object -Property 'DeviceServerName' -Value $DeviceServerName -EQ ).VideoDeviceList.VideoDevice |  Where-Object -Property 'VideoDeviceHostName' -Value $VideoDeviceHostName -EQ ).VideoDeviceCameraList.Camera.CameraUID
                foreach ($CameraUID in $CameraUIDs) {
                    [PSCustomObject]@{
                        Standort = $Standort
                        DeviceServerName = $DeviceServerName
                        VideoDeviceHostName = $VideoDeviceHostName
                        CameraUID =  $CameraUID
                    }
                }
            }
        }
    }
    


    Grüße - Best regards

    PS:> (79,108,97,102|%{[char]$_})-join''

    Coole Sache. Danke viel mal. Ihr habt mir den Tag gerettet....:-)
    Donnerstag, 19. Januar 2017 14:11