Reading XML data - problem with structure?

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of Soccer Soccer Soccer Soccer 1 year ago.

  • Author
    Posts
  • #33320
    Profile photo of Soccer Soccer
    Soccer Soccer
    Participant

    Hello Folks,
    maybe some1 can help me with this, I spent hours trying do fiddle it out.
    First of all, I'm done reading through google, I am here to get help because currently I believe something is wrong with the xml-file and to get a push to the right direction.

    My job is to monitor things, right now I am trying to write a little someting, reading in xml-data with Information about some queue states ("running", queued, errored, etc.).
    XML please see:

    1) I'm using powershell ISE, I am usually not into this, so any help is much apreciated!
    My aproach was:

    $xml = [XML] (Get-Content -Path xml.xml)
    $queues = $xml.applicationsPipelineInfo.applicationInfo
    

    second aproach is:

    $xml = [XML] (Get-Content -Path xml.xml)
    $xml.applicationsPipelineInfo.applicationInfo | % { $_.pipelineinfo}
    

    Thats the only way for me to get into data, a nice little table is shown with the correct entries. How would I filter these results or get only one line?

    I cant reach into the xml-classes deeper below"applicationinfo", getting to the various pipelinenames, etc. Is something wrong with the style of the XML?
    In my understanding the xml is already in an array, so accessing the different queues, states, etc. should be no problem? I should be able to get deeper and deeper into the document using dot notation.

    My goal would be a for-each-loop generating a write-host-new-line with the state, queue, name, etc. of every queue.

    Your help is much apreciated! Thank you!
    Julius

    PS apologies for the nickname 😀 (from googlemail)

  • #33325
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    If you're running PowerShell v3 or later, then you can use the dot notation if you like:

    $xml.applicationsPipelineInfo.applicationInfo.pipelineInfo
    
    $xml.applicationsPipelineInfo.applicationInfo.pipelineInfo.pipelineName
    
    # etc
    

    In PowerShell v2, you had to use ForEach-Object or other looping constructs, as you've done in your examples.

  • #33327
    Profile photo of Soccer Soccer
    Soccer Soccer
    Participant

    dave, thank you for your reply, unbelievable, its working and I can access the individual array-items. It was, indeed, powershell 2 and my inability.

  • #33347
    Profile photo of Dan Potter
    Dan Potter
    Participant

    This would give you a table without the hassle.

    $xml.selectnodes('applicationsPipelineInfo/applicationInfo/pipelineInfo')

  • #33349
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Make your own table. If you look at it long enough you'll see it:-)

    $xml.selectnodes('applicationsPipelineInfo/applicationInfo/pipelineInfo')|

    ForEach-object{
    [pscustomobject]@{

    pipename=$_.pipelinename
    appname = $_.parentnode.applicationname
    status = $_.status

    }
    }

  • #33377
    Profile photo of Soccer Soccer
    Soccer Soccer
    Participant

    Thank you for all your answers, meanwhile I made a little progress myself. My problem right now is comparing values from the XML. It seems that the IF Cause doesnt like the integers from the XML-queued or errored-object.

    $queued_warn = 5
    $queued_crit = 10
    $errored_warn = 5
    $errored_crit = 20
    $status = 0
    $statusmsg = "OK"
    
    #[...]
    $queues  = $xml.applicationsPipelineInfo.applicationInfo.status.Count
    $counter = 0
    while ($counter -le $queues) {
    $name_queue = $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.pipelineName[$counter].replace(" ","_").replace("-","")
    
    ### the comparing of online/offline-string is working fine:
      if (-not ($xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.status[$counter]) -eq ('ONLINE') )
        {
        $schnittstelle = "offline" 
        $status = 2
        $statusmsg = "CRIT"
        ausgabe # thats a function handling the output
        $counter++
    
    ## comparing if the two integers from .queued and the variable queued_crit are not working:
       if (-not ($xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.queued[$counter]) -le ($queued_crit)) {
        $schnittstelle = "online, but too many queued objects! (more than $queued_crit)" 
        $status = 2
        $statusmsg = "CRIT" 
        ausgabe # thats a function handling the output
        $counter++
        continue
    }
    #[...]
    

    Thats the problem and its killing me right now.

    Any hint whats wrong with the ints? Thank you!

    BR

    [edit]
    omg.. bracket-settings! I am too long on this.

      if (-not ($xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.queued[$counter] -le $queued_crit)) {
    

    solved it!

  • #33400
    Profile photo of Soccer Soccer
    Soccer Soccer
    Participant

    Guys, its getting better. One problem bugs me:

    The first execution of the while-statement gives back false every time. All executions after that are ok and true:

    $queued_crit = 10
    $errored_crit = 20
    $status = 0
    $statusmsg = "OK"
    $counter = 0
    while ($counter -lt $queues) { 
    $name_queue = $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.pipelineName[$counter].replace(" ","_").replace("-","")
    
        if (-not ($xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.status[$counter] -eq 'ONLINE') ) {
        $schnittstelle = "offline" 
        $status = 2
        $statusmsg = "CRIT"
        ausgabe
        $counter++
        continue
        }
        
     #  $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.queued[$counter]
      # $queued_crit
       if  ($xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.queued[$counter] -gt $queued_crit)  {
        $schnittstelle = "online, but too many queued objects! (more than $queued_crit)" 
        $status = 2
        $statusmsg = "CRIT" 
        ausgabe
        $counter++
        continue
        }
    
    elseif ( $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.errored[$counter] -gt $errored_crit ) {
        $schnittstelle = "online, but too many errored objects! (more than $errored_crit)" 
        $status = 2
        $statusmsg = "CRIT" 
        ausgabe
        $counter++
        continue
    } 
    
        
    else { 
    
        $schnittstelle = "online"
        $status = 0 
        $statusmsg = "OK"
        ausgabe
        $counter++ 
        continue
    } }
    
    
    Function ausgabe {
    Write-Host echo $status $name_queue - is $schnittstelle $statusmsg - $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.queued[$counter] queued object/s - $xml.applicationsPipelineInfo.applicationInfo.pipelineinfo.errored[$counter] errored object/s
    } 

    THis is the outcome:

    echo 2 IDX__G5__Vertragsverwaltung - is online, but too many queued objects! (more than 10) CRIT - 9 queued object/s - 0 errored object/s # thats wrong
    echo 0 IDX__G5__A - is online OK - 0 queued object/s - 0 errored object/s
    echo 0 Rechnung - is online OK - 0 queued object/s - 0 errored object/s
    echo 0 ssst_Return - is online OK - 0 queued object/s - 0 errored object/s
    echo 2 HL7_MDM__G5 - is offline CRIT - 22 queued object/s - 17 errored object/s
    echo 2 CSV_HR__G5_Staff - is online, but too many queued objects! (more than 10) CRIT - 11 queued object/s - 0 errored object/s
    echo 2 IDX_HR__G5_Documents - is online, but too many queued objects! (more than 10) CRIT - 12 queued object/s - 0 errored object/s
    echo 2 HL7_ADT__G5_(Socket) - is online, but too many queued objects! (more than 10) CRIT - 13 queued object/s - 18 errored object/s
    

    any idea why the first execution is getting the variable wrong?

You must be logged in to reply to this topic.