Nikolay Dyukendzhiev
Nikolay Dyukendzhiev

Reputation: 21

Changing an element value in the XML file

Need help with changing an element value in below XML using PowerShell:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Root>
<Package>
<ID>001</ID>
<Quantity1>65465</Quantity1>
<Quantity2>CALC</Quantity2>
</Package>
<Package>
<ID>002</ID>
<Quantity1></Quantity1>
<Quantity2>1547625</Quantity2>
</Package>
</Root>

I need to loop through the XML file and

I've tried this code:

[XML]$XMLcontents = [XML](Get-Content $PathToTheFile)
foreach ($i in $XMLcontents.SelectNodes('/Root/Package')) {
   $_.Quantity2 = $_.Quantity1
}

but I'm getting the following error:

The property 'Quantity2' cannot be found on this object.

How to properly reference elements within a node <Package>?

Upvotes: 2

Views: 54

Answers (3)

user9952217
user9952217

Reputation:

# requires -version 6
(Select-Xml -Path C:\path\input.xml -XPath //Package).Node.ForEach{
   $node = $_
   switch ([Int32]$_.ID) {
      1 { $node.Quantity2 = $node.Quantity1 }
      2 {
         $node.Quantity1 = $node.Quantity2
         $node.Quantity2 = 'CALC'
      }
   }
   $node.OwnerDocument.Save('C:\path\input.xml')
}

Upvotes: 0

Adam
Adam

Reputation: 4188

XML in Powershell can be tricky. I'd do something like this...

[xml]$xmlDoc = @"
<?xml version="1.0" encoding="ISO-8859-1"?>
<Root>
<Package>
<ID>001</ID>
<Quantity1>65465</Quantity1>
<Quantity2>CALC</Quantity2>
</Package>
<Package>
<ID>002</ID>
<Quantity1></Quantity1>
<Quantity2>1547625</Quantity2>
</Package>
</Root>
"@

$xmlDoc.Root.Package

foreach ( $package in $xmlDoc.Root.Package ) {
    if ( $package.ID.Equals('001') ) {
        $package.Quantity2 = $package.Quantity1
    }

    if ( $package.ID.Equals('002') ) {
        $package.Quantity1 = $package.Quantity2
        $package.Quantity2 = 'CALC'
    }
}

$xmlDoc.Root.Package

That first part [xml]$xmlDoc = @"..."@ I'm creating your XML document. I've stuffed it in a big'ol here-string.

The $xmlDoc.Root.Package is there just to show you the original state of your data. You don't need this in your final product.

The foreach loop is where I make the changes. I loop through all the Package elements in the Root element. For each one, I check the ID element's value. If it's "001", I copy that package's Quantity2 element value to Quantity1. If it's "002", I copy Quantity2 to Quantity1 then add "CALC" to Quantity2. You can see how I'm assigning the values.

Hope this helps!

Upvotes: 0

ArcSet
ArcSet

Reputation: 6860

First to answer why that fails is becuase you are using $_ when you should be using $i in the foreach.

OK first lets make the object into XML in by declaring it

[xml]$XML = @"
<?xml version="1.0" encoding="ISO-8859-1"?>
<Root>
<Package>
<ID>001</ID>
<Quantity1>65465</Quantity1>
<Quantity2>CALC</Quantity2>
</Package>
<Package>
<ID>002</ID>
<Quantity1></Quantity1>
<Quantity2>1547625</Quantity2>
</Package>
</Root>
"@

Then we will search the root for each package

foreach($package in $XML.Root.Package){
}

Gather the values and switch them

$Q1 = $package.Quantity1
$package.Quantity1 = $package.Quantity2
$package.Quantity2 = $Q1

Full script

[xml]$XML = @"
<?xml version="1.0" encoding="ISO-8859-1"?>
<Root>
<Package>
<ID>001</ID>
<Quantity1>65465</Quantity1>
<Quantity2>CALC</Quantity2>
</Package>
<Package>
<ID>002</ID>
<Quantity1></Quantity1>
<Quantity2>1547625</Quantity2>
</Package>
</Root>
"@

foreach($package in $XML.Root.Package){
    $Q1 = $package.Quantity1
    $package.Quantity1 = $package.Quantity2
    $package.Quantity2 = $Q1
}

$XML.Root.Package

If you want to use SelectNodes then you can also do

foreach ($i in $XML.SelectNodes('/Root/Package')) {
    $Q1 = $i.Quantity1
    $i.Quantity1 = $i.Quantity2
    $i.Quantity2 = $Q1
}

$XML.SelectNodes('/Root/Package')

Upvotes: 1

Related Questions