0

I'm guessing this is pretty simple, I'm just starting with powershell and I can't seem to find a simple solution after a few hours searching the net.

Basically I have the following xml file

<Config>
<System>
<Server>
    <Name>host1</Name> 
    <Service>service1</Service>
    <Service>service2</Service>
</Server>
<Server>
    <Name>host2</Name> 
    <Service>service1</Service>
</Server>
</System>

<System2>
<Server>
    <Name>host1</Name> 
    <Service>service1</Service>
    <Service>service2</Service>
</Server>
<Server>
    <Name>host2</Name> 
    <Service>service1</Service>
     <Service>service2</Service>
     <Service>service3</Service>

</Server>
</System2>
</Config>

And I would like to get the contents into a jagged 2d array, so system would wind up as follows:

  • (host1),(service1,service2)
  • (host2),(service1)

Is it possible to iterate through each element and create such an array?

I'm hoping to store the data as above so that I can use [0][0] to reference the hostname and then [1][1..x] to reference all services for that host.

Does that make any sense?

Any help or better appraoch is greatly appreciated.

1 Answer 1

3

You might think about using a hashtable for this instead. You can still iterate over the results and you can look up results by hostname e.g.:

$xml = [xml]@'
    <Config>
    <System>
    <Server>
        <Name>host1</Name> 
        <Service>service1</Service>
        <Service>service2</Service>
    </Server>
    <Server>
        <Name>host2</Name> 
        <Service>service1</Service>
    </Server>
    </System>

    <System2>
    <Server>
        <Name>host1</Name> 
        <Service>service1</Service>
        <Service>service2</Service>
    </Server>
    <Server>
        <Name>host2</Name> 
        <Service>service1</Service>
        <Service>service2</Service>
        <Service>service3</Service>
    </Server>
    </System2>
    </Config>
'@

$ht = @{}
$hostnameNodes = $xml | Select-Xml -XPath '//Name'
foreach ($node in @($xml | Select-Xml -XPath '//Name'))
{
    $hostname = $node.Node.InnerText.Trim()
    $services = @($node.Node.ParentNode.Service)
    foreach ($service in $services)
    {
        $ht["$hostname"] += @($service.Trim())
    }
}

$ht

Outputs:

Name                           Value                                    
----                           -----                                    
host1                          {service1, service2, service1, service2} 
host2                          {service1, service1, service2, service3} 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the swift response. Just to clarify as like I said i'm pretty new to all this, your solution will basically create a hash table but replace one of the key value pairs with an array of services?
It creates an entry for each host name and the value for that entry will be an array of service names.
Brilliant, thank you very much, your help and advice is much appreciated. I will definitely have a go at this tomorrow. I just tested the code above and seems to assign nulls to the services, so i'm guessing i'll need to do a little playing around with it, but it's all part of learning :-)
Apologies for the follow up question, I have realised what I really want is the ability to extract all the data into a hash table for a specific system... so for example just the data within the <System> ....... </System> tags, so basically create a has table for each hostname and associated services that make up a "system"
if I amend the Select-Xml -XPath parts will I be able to achieve this? Thanks again for the help
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.