Search code examples
xmlpowershellnodes

Edit nodes in result with certain values


Hi im trying to read my nodes from a xml in powershell. Then i have to find the Invalid Nodes (when ArrayDimensions is available and Childnode got ReferenceType= "HasComponent```. Then i want to delete this Node from my Result. Code:

[xml]$uar = Get-Content -Path '.\OpcUaMap(3)_28_07.uar'

$ns = New-Object System.Xml.XmlNamespaceManager($uar.NameTable)

$ns=@{test="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd";
    ua="ua="http://xxx/NodeSet.xsd";
    xsi="http://www.w3.org/2001/XMLSchema-instance";
    uax="http://opcfoundation.org/UA/2008/02/Types.xsd";
    xsd="http://www.w3.org/2001/XMLSchema";
    pv="http://yyy/NodeSet.xsd"}

$result=Select-xml -xml $uar -xpath "//test:UAVariable[contains(@NodeId,'ns=1;s=::')][starts-with(@DataType,'i=')]" -namespace $ns  | select -ExpandProperty node

write host $result

$result | ConvertTo-Html`
 -Property DataType, NodeId `
 > ".\result.html"

XML:

<?xml version="1.0" encoding="utf-8"?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns:ua="http://xxx/NodeSet.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pv="http://yyy/NodeSet.xsd" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
    <UAObject NodeId="ns=1;s=::" BrowseName="1:::">
        <DisplayName>&lt;Default&gt;</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">ns=2;i=10001</Reference>
            <Reference ReferenceType="Organizes" IsForward="false">ns=2;i=20001</Reference>
            <Reference ReferenceType="Organizes">ns=1;s=::AsGlobalPV</Reference>
            <Reference ReferenceType="Organizes">ns=1;s=::Program</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:ObjectExtension>
                    <ACL>
                        <ACE Role="1" Allow="0x017F"/>
                        <ACE Role="2" Allow="0x015F"/>
                    </ACL>
                </pv:ObjectExtension>
            </Extension>
        </Extensions>
    </UAObject>
    <UAObject ParentNodeId="ns=1;s=::" NodeId="ns=1;s=::AsGlobalPV" BrowseName="1:Global PV">
        <DisplayName>Global PV</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=61</Reference>
            <Reference ReferenceType="Organizes" IsForward="false">ns=1;s=::</Reference>
            <Reference ReferenceType="Organizes">ns=1;s=::AsGlobalPV:gFahrzeug</Reference>
            <Reference ReferenceType="Organizes">ns=1;s=::AsGlobalPV:gLebewesen</Reference>
        </References>
    </UAObject>
    <UAVariable DataType="ns=1;i=100000" ParentNodeId="ns=1;s=::AsGlobalPV" NodeId="ns=1;s=::AsGlobalPV:gFahrzeug" BrowseName="1:gFahrzeug" AccessLevel="3" ValueRank="-1">
        <DisplayName>gFahrzeug</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">ns=1;i=100005</Reference>
            <Reference ReferenceType="HasComponent">ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:VariableExtension AuditEvents="true">
                    <Value>
                        <Binding Type="PV" Target="::gFahrzeug"/>
                    </Value>
                </pv:VariableExtension>
            </Extension>
        </Extensions>
    </UAVariable>
    <UAVariable DataType="ns=1;i=100010" ParentNodeId="ns=1;s=::AsGlobalPV:gFahrzeug" NodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug" BrowseName="1:Kraftfahrzeug" AccessLevel="3" ValueRank="-1">
        <DisplayName>Kraftfahrzeug</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">ns=1;i=100015</Reference>
            <Reference ReferenceType="HasComponent">ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW</Reference>
            <Reference ReferenceType="HasComponent">ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.PKW</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:VariableExtension AuditEvents="true">
                    <Value>
                        <Binding Type="PV" Target="::gFahrzeug.Kraftfahrzeug"/>
                    </Value>
                </pv:VariableExtension>
            </Extension>
        </Extensions>
    </UAVariable>
    <UAVariable DataType="i=3" ParentNodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug" NodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW" BrowseName="1:LKW" AccessLevel="3" ValueRank="1" ArrayDimensions="2">
        <DisplayName>LKW</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
            <Reference ReferenceType="HasComponent">ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[0]</Reference>
            <Reference ReferenceType="HasComponent">ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[1]</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:VariableExtension AuditEvents="true">
                    <Value>
                        <Binding Type="PV" Target="::gFahrzeug.Kraftfahrzeug.LKW"/>
                    </Value>
                </pv:VariableExtension>
            </Extension>
        </Extensions>
    </UAVariable>
    <UAVariable DataType="i=3" ParentNodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW" NodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[0]" BrowseName="1:LKW[0]" AccessLevel="3">
        <DisplayName>LKW[0]</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:VariableExtension AuditEvents="true">
                    <ACL>
                        <ACE Role="1" Allow="0x017F"/>
                        <ACE Role="2" Allow="0x015F"/>
                    </ACL>
                    <Value>
                        <Binding Type="PV" Target="::gFahrzeug.Kraftfahrzeug.LKW[0]"/>
                    </Value>
                </pv:VariableExtension>
            </Extension>
        </Extensions>
    </UAVariable>
    <UAVariable DataType="i=3" ParentNodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW" NodeId="ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[1]" BrowseName="1:LKW[1]" AccessLevel="3">
        <DisplayName>LKW[1]</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
        </References>
        <Extensions>
            <Extension>
                <pv:VariableExtension AuditEvents="true">
                    <ACL>
                        <ACE Role="1" Allow="0x017F"/>
                        <ACE Role="2" Allow="0x015F"/>
                    </ACL>
                    <Value>
                        <Binding Type="PV" Target="::gFahrzeug.Kraftfahrzeug.LKW[1]"/>
                    </Value>
                </pv:VariableExtension>
            </Extension>
        </Extensions>
    </UAVariable>
</UANodeSet>

My Result is:

DataType        : i=3
ParentNodeId    : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug
NodeId          : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW
BrowseName      : 1:LKW
AccessLevel     : 3
ValueRank       : 1
ArrayDimensions : 2
DisplayName     : LKW
References      : References
Extensions      : Extensions

DataType     : i=3
ParentNodeId : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW
NodeId       : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[0]
BrowseName   : 1:LKW[0]
AccessLevel  : 3
DisplayName  : LKW[0]
References   : References
Extensions   : Extensions

DataType     : i=3
ParentNodeId : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW
NodeId       : ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW[1]
BrowseName   : 1:LKW[1]
AccessLevel  : 3
DisplayName  : LKW[1]
References   : References
Extensions   : Extensions

so its working. Now i want to erase invalid Value like ns=1;s=::AsGlobalPV:gFahrzeug.Kraftfahrzeug.LKW because this is the declaration of the array and its invalid to be displayed. How i have to get rid of it: Every node Displayname but not all got Arraydimensions so if Arraydimensions is available (not emtpy) and ReferenceType got a Value in in its a invalid node. I have tried is something with EDIT:

$result | foreach {
    $AttExists = $_.Arraydimensions
    $NodeExists = $_.ReferenceType
    if ($AttExists){
        if ($NodeExists = 'HasComponent'){
            Write-Host 'Delete'
        }
        else{
            Write-Host 'OK'
        }
    }
    else{
        Write-Host 'OK'
    }
}

Result:

Delete
OK
OK
OK
Delete
OK
OK
OK
Delete
OK
OK

it seems he didnt look in my referencetype for "HasComponent" because the last delete is wrong It should be this:

Delete
OK
OK
OK
Delete
OK
OK
OK
OK
OK
OK

Solution

  • Here is one way you can remove the desired node.

    [xml]$uar = Get-Content -Path C:\temp\test.uar -Encoding UTF8
    
    [xml]$uar = Get-Content -Path '.\OpcUaMap(3)_28_07.uar'
    
    $ns = New-Object System.Xml.XmlNamespaceManager($uar.NameTable)
    
    $ns=@{
        test="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd";
        ua="http://xxx/NodeSet.xsd";
        xsi="http://www.w3.org/2001/XMLSchema-instance";
        uax="http://opcfoundation.org/UA/2008/02/Types.xsd";
        xsd="http://www.w3.org/2001/XMLSchema";
        pv="http://yyy/NodeSet.xsd"
    }
    
    $result = Select-xml -xml $uar -xpath "//test:UAVariable[contains(@NodeId,'ns=1;s=::')][starts-with(@DataType,'i=')]" -namespace $ns  | select -ExpandProperty node
    
    $nodetodelete = $result | where {$_.hasattribute("ArrayDimensions")}
    
    $nodetodelete.ParentNode.RemoveChild($nodetodelete)
    

    It should show you the node that got removed. If you want to suppress that output you can just assign the output to $null

    $null = $nodetodelete.ParentNode.RemoveChild($nodetodelete)
    

    You can also confirm it's removed by rerunning your query and confirming there are only 2 now.

    Select-xml -xml $uar -xpath "//test:UAVariable[contains(@NodeId,'ns=1;s=::')][starts-with(@DataType,'i=')]" -namespace $ns  | select -ExpandProperty node
    

    or

    Select-xml -xml $uar -xpath "//test:UAVariable[contains(@NodeId,'ns=1;s=::')][starts-with(@DataType,'i=')]" -namespace $ns  | measure | select -expand count