尝试使用 powershell 更新 xml 文档但在更新根节点时遇到问题
Trying to update xml document with powershell but having issue updating root node
文档示例:
<?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>
我可以像这样给 displayName 和 firstname 赋值没问题:
[string] $displayvalue = $xmldata.Identity.Attributes.Map.entry[0].value
[string] $firstname = $xmldata.Identity.Attributes.Map.entry[1].value
然后保存。
$myFile = 'C:\somefile.xml'
$xmldata.Save($myFile)
但是当我尝试对名称执行相同操作时:
[string] $xmldata.Identity.Name = "TEST"
我收到一个错误:
在此对象上找不到 属性 'Name'。确认 属性 存在并且可以设置。
谢谢
XML 区分大小写,因为在
<Identity created="1525465321820" name="Onboarding - GUI - External">
"name"是小写,需要用
$xmldata.Identity.name
相对于
$xmldata.Identity.Name
并使用
编辑值
$xmldata.Identity.name = "TEST"
正在测试
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
如果要导入 xml 文件并执行此操作,请执行以下操作:
- 设置一个变量作为xml文件的内容但跳过前两行并设置另一个作为前两行
[xml]$var = Get-Content .\test.xml | select-object -skip 2
$var2 = Get-Content .\test.xml | select-object -first 2
- 使用
$var
上述方法
$var.Identity.name
输出:
Onboarding - GUI - External
输入:
$var.Identity.name = "TEST"
$var.Identity.name
输出:
TEST
- 然后将 header 添加回变量
[xml]$final = $var2 + $var.outerxml
- 最后,将变量保存回XML文件
$final.Save("filepath")
关于
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>
Powershell 似乎不喜欢,因此如果您跳过它们,它会正常工作...
在 Powershell 5.1 中测试
稍微 更改了您的 XML 文件,因为 PS 在我使用您的确切 XML 时给我错误,因为那里没有关闭 </map>
您不是尝试对 name
属性进行与对 displayname
和 firstname
属性相同的操作。
对于后两者,您正在 READING 字符串变量中 XML 的值。使用 name
属性,您正在尝试将其 SET 设置为新值。
为此,您首先需要 select 包含要更新的属性的元素。完成后,您可以使用 XmlElement 对象的 SetAttribute()
方法。
[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')
输出:
<?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>
文档示例:
<?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>
我可以像这样给 displayName 和 firstname 赋值没问题:
[string] $displayvalue = $xmldata.Identity.Attributes.Map.entry[0].value
[string] $firstname = $xmldata.Identity.Attributes.Map.entry[1].value
然后保存。
$myFile = 'C:\somefile.xml'
$xmldata.Save($myFile)
但是当我尝试对名称执行相同操作时:
[string] $xmldata.Identity.Name = "TEST"
我收到一个错误:
在此对象上找不到 属性 'Name'。确认 属性 存在并且可以设置。
谢谢
XML 区分大小写,因为在
<Identity created="1525465321820" name="Onboarding - GUI - External">
"name"是小写,需要用
$xmldata.Identity.name
相对于
$xmldata.Identity.Name
并使用
编辑值$xmldata.Identity.name = "TEST"
正在测试
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
如果要导入 xml 文件并执行此操作,请执行以下操作:
- 设置一个变量作为xml文件的内容但跳过前两行并设置另一个作为前两行
[xml]$var = Get-Content .\test.xml | select-object -skip 2
$var2 = Get-Content .\test.xml | select-object -first 2
- 使用
$var
上述方法
$var.Identity.name
输出:
Onboarding - GUI - External
输入:
$var.Identity.name = "TEST"
$var.Identity.name
输出:
TEST
- 然后将 header 添加回变量
[xml]$final = $var2 + $var.outerxml
- 最后,将变量保存回XML文件
$final.Save("filepath")
关于
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Identity PUBLIC "point.dtd" "point.dtd"[]>
Powershell 似乎不喜欢,因此如果您跳过它们,它会正常工作...
在 Powershell 5.1 中测试
稍微 更改了您的 XML 文件,因为 PS 在我使用您的确切 XML 时给我错误,因为那里没有关闭 </map>
您不是尝试对 name
属性进行与对 displayname
和 firstname
属性相同的操作。
对于后两者,您正在 READING 字符串变量中 XML 的值。使用 name
属性,您正在尝试将其 SET 设置为新值。
为此,您首先需要 select 包含要更新的属性的元素。完成后,您可以使用 XmlElement 对象的 SetAttribute()
方法。
[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')
输出:
<?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>