xml - 使用 PowerShell 从 XML 更新字符串
问题描述
我正在从一些 XML 数据中检索文本字符串,然后尝试用其他内容替换该字符串。我正在使用的代码是:
$newstring = "mystring"
$bar = Get-Gpo -Name "My GPO"
$gpoid = $bar.Id.ToString()
$drivesxml = New-Object XML
$drivesxml.Load("\\mydomain.co.uk\sysvol\mydomain.co.uk\Policies\{gpoid}\User\Preferences\Drives\drives.xml")
$oldpath = $drivesxml.Drives.Drive.Properties.Path[0]
$oldlabel = $drivesxml.Drives.Drive.Properties.Label[0]
#1
[string]$newtemppath = $oldpath -replace "Oldstring$", "$newstring"
[string]$newtemplabel = $oldlabel -replace "^Oldstring", "$newstring"
#2
$drivesxml.Drives.Drive.Properties.Path[0] = $newtemppath
$drivesxml.Drives.Drive.Properties.Label[0] = $newtemplabel
#3
$drivesxml.Save("\\mydomain.co.uk\sysvol\mydomain.co.uk\Policies\{gpoid}\User\Preferences\Drives\drives.xml")
它很好地从 sysvol 中检索 XML,如果我查询$oldpath
并且$oldlabel
它们包含来自 XML 的预期文本,则在第 1 点。
在#2,如果我查询$newtemppath
并且$newtemplabel
字符串按预期返回并修改了文本,因此“Oldstring”的实例已被“mystring”替换。
在#3,如果我查询$drivesxml.Drives.Drive.Properties.Path[0]
并且$drivesxml.Drives.Drive.Properties.Label[0]
我希望它们返回与$newtemppath
and$newtemplabel
变量相同的内容,但它们会继续返回其原始值。
如果我再次查询,保存 XML 后,内容没有改变。
谁能看到我在 #2 和 #3 之间的分配可能做错了什么?
解决方案
Powershell 支持用于导航 XML 文件的“点路径”语法,这对于从 XML 文件读取数据非常方便——大概是为了方便使用 XML 输入或使用 XML 配置文件。
该语法的缺点是它会尽可能地尝试返回字符串和数组。在您的情况下,$drivesxml.Drives.Drive.Properties.Path[0]
是一个字符串,而不是 XML 节点,因此您分配给该值的任何内容都将丢失。
诀窍是保留 XML 节点。实现这一点的最简单方法是使用 XPath 进行导航(无论如何它比点路径语法更强大):
$path = $drivesxml.SelectSingleNode('/Drives/Drive/Properties/Path')
$path.InnerText = $path.InnerText -replace "Oldstring$",$newstring
# ...
$drivesxml.Save($xmlPath)
您还可以使用.SelectNodes
和foreach
循环来进行多项更改。
在不相关的说明中,Powershell 将在双引号字符串中进行变量插值。这可能与正则表达式发生冲突,其中$
有其自身的含义。在上面的例子中没有歧义,但最好养成使用单引号字符串作为正则表达式的习惯:
$path.InnerText = $path.InnerText -replace 'Oldstring$',$newstring
关于 XML 命名空间的说明:如果您的 XML 文件使用命名空间xmlns
(由)?
推荐阅读
- c# - 创建服务器和客户端证书
- node.js - 骨料管柱成型
- flutter - 如何在不使用 RepaintBoundary 的情况下从小部件树中获取快照?
- java - Java RMI:作为主服务器和备份服务器的客户端
- javascript - JS - 如何将动态对象添加到数组 [代码]
- linux - 带有 LEGACY_MAP_MASK 的 MAP_SHARED_VALIDATE 在 mmap() 中产生 EINVAL 错误
- php - 如何更改日历中的默认值
- python - 使用 Azure 表单识别器提取 PDF 表数据
- javascript - 在 discord.js 中创建重启命令
- sql - SQL中某列的行号