【问题标题】:Trying to update xml document with powershell but having issue updating root node尝试使用 powershell 更新 xml 文档但在更新根节点时遇到问题
【发布时间】:2020-06-04 19:33:36
【问题描述】:

文档示例:

<?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)

但是当我尝试对 name 做同样的事情时:

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

我遇到了一个错误:

在此对象上找不到属性“名称”。验证该属性是否存在并且可以设置。

谢谢

【问题讨论】:

  • 错误就是它看起来的样子,xml 文件中没有 name 属性,除非 $myfile 文件中有不同的内容,请向我们提供相关信息
  • 嗨 Neko,名字就在那里 name="Onboarding - GUI - External"。从顶部开始的第 3 行。感谢您的回复。
  • 哎呀,我的错...它可能需要不同的命令才能访问,因为它在属性内...尝试$xmldata | get-member 看看是否有命令
  • &lt;map&gt; 属性是否正确?没有关闭&lt;/map&gt;
  • Thx Neko,有很多命令,抱歉,对 powershell 很陌生,不确定。这个怎么用..

标签: powershell xml-parsing


【解决方案1】:

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 文件并执行以下操作:

  1. 将一个变量设置为 xml 文件的内容,但跳过前 2 行并将另一个设置为前 2 行
[xml]$var = Get-Content .\test.xml | select-object -skip 2
$var2 = Get-Content .\test.xml | select-object -first 2
  1. 使用$var上述方法
$var.Identity.name

输出:

Onboarding - GUI - External

输入:

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

输出:

TEST
  1. 然后将标头添加回变量
[xml]$final = $var2 + $var.outerxml
  1. 最后,将变量保存回 XML 文件
$final.Save("filepath")

关于

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

Powershell 似乎不喜欢,因此如果你跳过它们,它工作正常...

在 Powershell 5.1 中测试


稍微更改了您的 XML 文件,因为当我使用您的确切 XML 时 PS 给了我错误,因为没有关闭 &lt;/map&gt;

【讨论】:

【解决方案2】:

没有name 属性尝试与displaynamefirstname 属性相同的操作。
对于后两者,您是 READING 字符串变量中 XML 的值。使用name 属性,您正尝试将其SET 设置为新值。

为此,您首先需要选择包含要更新的属性的元素。一旦你有了它,你就可以使用 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>

【讨论】:

  • 嗨 Theo,太好了,我还有 1 个问题,我并不总是知道 name 的 name 值是什么。如果我没有在 $_.name -like '' 下指定任何内容,我的方法调用失败,但它仍然会更改值。那应该没问题。我还有一个更大的问题。我正在更改的文件最初是 UNIX )(LF) UTF-8 ,但是当 Powershell 读写时,他们将所有文件都插入到带有空格的 Windows (CR LF) UTF-8-BOM 中,它们并不好。你知道如何保持相同的格式吗?非常感谢您的帮助。
  • @Evo 我看到你已经发布了一个关于 Unix 格式与 Windows 的新问题。我回答了您在此处发布的问题。对 SO 很陌生,您可能不知道这一点,但习惯上通过单击旁边的复选标记图标来接受解决您问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2021-04-30
相关资源
最近更新 更多