Search code examples
xmlpowershellidref

how to find xml node by idref in powershell


for example, I have simple xml

<A>
    <networks type="A">
        <hub id = "123">
            <port>8080</port>
        </hub>
        <client idref = "123">
            <host>some.value</host>
        </client>
    </networks>
</A>
<B>
    <networks type="B">
        <hub id = "235">
            <port>9090</port>
        </hub>
        <client idref = "235">
            <host>some.value</host>
        </client>
    </networks>
</B>

I iterate through network items/nodes using foreach loop with specific type.

 $networks = ($variable.SelectNodes('//networks') | Where-Object {$_.type -eq "$type*"})
foreach ($node in $networks) {
    if($node.hub -ne $null) {
        Write-Output 'hub:'
        Write-Output 'id' $node.hub.id
        Write-Output 'port' $node.hub.port
        Write-Output '*********'
    }
    if($node.client -ne $null) {
        Write-Output 'client:'
        Write-Output 'idref:' $node.client.idref
        Write-Output 'host:' $node.client.host 
        # how to pick port from networks//hub//port where hub.id = 123 by $node.client.idref here?
        Write-Output '**********'
    }
}

but when current node is "client", I need to distinguish port from "hub" tag by idref. How to do this?


Solution

  • I might be misunderstanding, but does this work?

    $xml = [xml] @"
    <root>
        <A>
            <networks type="A">
                <hub id = "123">
                    <port>8080</port>
                </hub>
                <client idref = "123">
                    <host>some.value</host>
                </client>
            </networks>
        </A>
        <B>
            <networks type="B">
                <hub id = "235">
                    <port>9090</port>
                </hub>
                <client idref = "235">
                    <host>some.value</host>
                </client>
            </networks>
        </B>
    </root>
    "@
    
    $networks = $xml.SelectNodes('//networks') 
    foreach ($node in $networks) {
        if ($null -ne $node.hub) {
            Write-Output 'hub:'
            Write-Output 'id' $node.hub.id
            Write-Output 'port' $node.hub.port
            Write-Output '*********'
        }
        if ($null -ne $node.client) {
            Write-Output 'client:'
            Write-Output 'idref:' $node.client.idref
            Write-Output 'host:' $node.client.host 
    
            # how to pick port from networks//hub//port where hub.id = 123 by $node.client.idref here?
            Write-Output 'port: ' ($xml.SelectNodes('//networks') | Where-Object { $_.hub.id -eq $node.client.idref }).hub.port
            Write-Output "**********"  
        }
    }