Reputation: 21
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
cut value from <Quantity1>
and paste it to <Quantity2>
in the first case (ID:001).
cut value from <Quantity2>
, paste it to <Quantity1>
and make <Quantity2>
equals to 'CALC' in the second case (ID:002).
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
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
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
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