0

Doc Example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>
<Identity  created="1525465321820" name="Onboarding - GUI - External">
  <Attributes>
    <Map>
      <entry key="displayName" value="Onboarding - GUI " />
      <entry key="firstname" value="Z Orphaned ID" />
  </Attributes>
</Identity>

I can assign values to displayName and firstname no problem like so:

[string] $displayvalue = $xmldata.Identity.Attributes.Map.entry[0].value

[string] $firstname = $xmldata.Identity.Attributes.Map.entry[1].value

and than save.

$myFile = 'C:\somefile.xml'
$xmldata.Save($myFile)

BUT when I try to do the same for name :

[string]  $xmldata.Identity.Name = "TEST"

I got an error :

The property 'Name' cannot be found on this object. Verify that the property exists and can be set.

Thanks

Evo
  • 41
  • 5
  • The error is exactly what it looks like, there is no name property on the xml file unless there is something different on the `$myfile` file in which please provide us with the information on that – Nico Nekoru Jun 04 '20 at 19:41
  • Hi Neko, the name is right there name="Onboarding - GUI - External". 3rd line from the top. Thanks for the reply. – Evo Jun 04 '20 at 19:46
  • Oops, my bad... It might require a different command to access since it is inside the property... Try `$xmldata | get-member` to see if there are commands for it – Nico Nekoru Jun 04 '20 at 19:52
  • Is the `` property correct? There is no closing `` – Nico Nekoru Jun 04 '20 at 19:59
  • Thx Neko, There a tons of commands , sorry so new to powershell not sure. How to use this.. – Evo Jun 04 '20 at 20:00
  • Oh, I found the error, XMLs are case sensitive, try `$xmldata.Identity.name` worked for me – Nico Nekoru Jun 04 '20 at 20:01
  • I tried with this one. Identity Property System.Object[] Identity {get;} – Evo Jun 04 '20 at 20:01
  • What do you mean by 'this one'? – Nico Nekoru Jun 04 '20 at 20:02
  • Hi Neko, The problem is not getting the value .. That works I can get the value.. But when I try to assign a new value to it like this : [string] $xmldata.Identity.name = "TEST" I get an error :The property 'name' cannot be found on this object. Verify that the property exists and can be set. – Evo Jun 04 '20 at 20:03
  • Try using the lowercase `name` with the `$xmldata.Identity.name = "TEST"` – Nico Nekoru Jun 04 '20 at 20:04
  • I did it is lowercase $xmldata.Identity.name = "TEST". – Evo Jun 04 '20 at 20:07
  • Yep, case-sensitive languages can be fickle sometimes... :-\ – Nico Nekoru Jun 04 '20 at 20:09
  • See if my answer works now : ) – Nico Nekoru Jun 04 '20 at 20:38

2 Answers2

2

XMLs are case sensitive and since in

<Identity  created="1525465321820" name="Onboarding - GUI - External">

"name" is lowercase, you need to use

$xmldata.Identity.name

As oppose to

$xmldata.Identity.Name

and to edit the value use

$xmldata.Identity.name = "TEST"

TESTING

PS C:\Users\Neko> [xml]$xmldata = @'
>> <Identity  created="1525465321820" name="Onboarding - GUI - External">
>>   <Attributes>
>>     <Map>
>>       <entry key="displayName" value="Onboarding - GUI " />
>>       <entry key="firstname" value="Z Orphaned ID" />
>>     </Map>
>> </Attributes>
>> </Identity>
>> '@
PS C:\Users\Neko> $xmldata.Identity.name
Onboarding - GUI - External
PS C:\Users\Neko> $xmldata.Identity.name = "TEST"
PS C:\Users\Neko> $xmldata.Identity.name
TEST

If you want to import an xml file and do this do the following:

  1. Set a variable as the content of the xml file but skip the first 2 lines and set another as the first 2 lines
[xml]$var = Get-Content .\test.xml | select-object -skip 2
$var2 = Get-Content .\test.xml | select-object -first 2
  1. Use $var the ways demonstrated above
$var.Identity.name

Output:

Onboarding - GUI - External

Input:

$var.Identity.name = "TEST"
$var.Identity.name

Output:

TEST
  1. Then add the header back to the variable
[xml]$final = $var2 + $var.outerxml
  1. Finally, save the variable back to the XML file
$final.Save("filepath")

Something about

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>

Powershell seems to not like, therefore if you skip them it works fine...

Tested in Powershell 5.1


Slightly changed your XML file since PS gave me errors when I used your exact XML since there was no closing </map>

Nico Nekoru
  • 2,840
  • 2
  • 17
  • 38
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/215349/discussion-on-answer-by-neko-musume-trying-to-update-xml-document-with-powershel). – Samuel Liew Jun 05 '20 at 05:09
0

You are not trying the same thing for the name attribute as you do for the displayname and firstname attributes.
With the latter two, you are READING the values from the XML in string variables. With the name attribute, you are trying to SET it to a new value.

To do that, you first need to select the element that holds the attribute to update. Once you have that, you can use the SetAttribute() method of the XmlElement object(s).

[xml]$xmldata = @"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>
<Identity  created="1525465321820" name="Onboarding - GUI - External">
  <Attributes>
    <Map>
      <entry key="displayName" value="Onboarding - GUI " />
      <entry key="firstname" value="Z Orphaned ID" />
    </Map>
  </Attributes>
</Identity>
"@

# select the node(s) to update, and update the name attribute
$xmldata.Identity | Where-Object { $_.name -like 'Onboarding*' } | ForEach-Object {
    $_.SetAttribute("name", "TEST")
}

# Now save the updated XM to file:
$xmldata.Save('C:\somefile.xml')

Output:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>
<Identity created="1525465321820" name="TEST">
  <Attributes>
    <Map>
      <entry key="displayName" value="Onboarding - GUI " />
      <entry key="firstname" value="Z Orphaned ID" />
    </Map>
  </Attributes>
</Identity>
Theo
  • 57,719
  • 8
  • 24
  • 41
  • Hi Theo, This is great I just have 1 more problem, I don't always know what the name value for name is going to be. if I don't specify anything under $_.name -like '' I got an Method invocation failed, but it still changes the value. That should be ok. I have another bigger issue. The files i'm changing were originaly UNIX )(LF) UTF-8 , but when Powershell read write they got all mestup in to Windows (CR LF) UTF-8-BOM with spaces , they are no good. DO you know how to keep the same format? Thanks so much for the help. – Evo Jun 05 '20 at 14:37
  • @Evo I see you already posted a new question about Unix format vs Windows. I answered the question you posted here. Being quite new to SO you may not know this, but it is customary to accept the answer that solved your problem by clicking the checkmark icon next to it. – Theo Jun 05 '20 at 20:03