0

I have another question. I have an XML document that I would like to update a couple of nodes. I'm looking to copy/clone the device name node to a new node. For a more of an understanding here is the sample XML document:

<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Enclave id="OLD">
        <device>
            <name>G-VDS-GooD</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC001</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC002</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
    </Enclave>
</Configuration>

Here is what I'm trying to get to:

<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Enclave id="OLD">
        <device>
            <name>G-VDS-GooD</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC001</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <cert>
              <name>G-VDS-ENC001</name>
            </cert>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC002</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <cert>
              <name>G-VDS-ENC002</name>
            </cert>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
    </Enclave>
</Configuration>

Here is my code:

$LoadType = "OLD"
$FileName = "C:\name.xml" 
[xml]$FileOriginal = Get-Content $FileName
$Pattern = $FileOriginal.SelectNodes("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(), 'G-VDS-ENC')]]")

foreach($Pat in $Pattern) {
    $device = $FileOriginal.SelectSingleNode("//Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(), 'G-VDS-ENC')]]")
    $devicename = $device.name;
    $name = $FileOriginal.CreateElement('name')

    foreach($name in $device) {
    $devicename = $device.name;
    $name = $FileOriginal.CreateElement('name')
    $name.InnerText = "$devicename"
    }

    $cert = $FileOriginal.CreateElement('cert')

    $cert.AppendChild($name)

    $Pat.InsertAfter( $cert, $Pat.SelectSingleNode('vlan') ) 

}

$FileOriginal.Save($FileName)

Here was the result:

<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Enclave id="OLD">
        <device>
            <name>G-VDS-GooD</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC001</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <cert>
              <name>G-VDS-ENC001</name>
            </cert>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
        <device>
            <name>G-VDS-ENC002</name>
            <type>VoIP</type>
            <vlan>Voice2Network</vlan>
            <cert>
              <name>G-VDS-ENC001</name>
            </cert>
            <inform>PEM</inform>
            <outform>PEM</outform>
            <RequireCert>0</RequireCert>
        </device>
    </Enclave>
</Configuration>

I tried to accomplish this through a foreach syntax but I don't know or think thats the correct approach. I also tried a different approach in using the CloneNode cmdlet but I couldn't get that to work either. Anyone have an idea on how to make this work?

0

1 Answer 1

1

I think the code is trying to do too much. Some minor simplification should make it work as desired:

$LoadType = "OLD"
$FileName = "c:\name.xml" 
[xml]$FileOriginal = Get-Content $FileName
$Pattern = $FileOriginal.SelectNodes("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(), 'G-VDS-ENC')]]")

foreach($Pat in $Pattern) {
    # new name node
    $name = $FileOriginal.CreateElement('name')
    # set node text to the current device name
    $name.InnerText = $Pat.name
    # new cert node
    $cert = $FileOriginal.CreateElement('cert')
    # add name node as child of cert node
    $cert.AppendChild($name)
    # insert new cert node after current device's vlan node
    $Pat.InsertAfter( $cert, $Pat.SelectSingleNode('vlan') ) 

}

$FileOriginal.Save($FileName)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much. It worked. I need to go back and study exactly where my logic wasn't correct. Thanks again.
Since $Pattern already selected device nodes, the foreach ($pat in $pattern) made $pat be each single device. You did not need to do another foreach. So $device = $pat would have been what you wanted theoretically.

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.