使用 PowerShell 更改 XML 元素值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42699869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change XML Element value with PowerShell
提问by Kahn Kah
I'm only finding stuff on how to change the attribute values of a XML element here on StackOverflow.
我只是在 StackOverflow 上找到有关如何更改 XML 元素的属性值的内容。
But how do we change the value of the element itself using PowerShell?
但是我们如何使用 PowerShell 更改元素本身的值?
I currently have:
我目前有:
XML
XML
<Task>
<Settings>
...
</Settings>
<Actions Context="Author">
<Exec>
<Command>blablabla</Command>
<Arguments>CHANGETHISVALUE</Arguments>
</Exec>
</Actions>
</Task>
SCRIPT
脚本
$filePathToTask = C:\Task.xml
$xml = New-Object XML
$xml.Load($filePathToTask)
$element = $xml.SelectSingleNode("//Arguments")
$element.InnerText("newtext")
$xml.Save($filePathToTask)
However, I can't seem to use methods on the last variable. What am I doing wrong?
但是,我似乎无法对最后一个变量使用方法。我究竟做错了什么?
Edit
编辑
- Added code
- 添加代码
The error that I'm getting is You cannot call a method on a null-valued expression
我得到的错误是你不能在空值表达式上调用方法
I think my problem lies at:
我认为我的问题在于:
$ElementToChange = $xml.SelectSingleNode("//Arguments")
Which stays null, but I have tried methods like .SelectNodesand playing around with the //Argumentstag but still no success
它保持为空,但我尝试过类似的方法.SelectNodes并使用//Arguments标签,但仍然没有成功
回答by Ansgar Wiechers
InnerTextis a property, not a method. It's used like this:
InnerText是一个属性,而不是一个方法。它是这样使用的:
$element.InnerText = "newtext"
Also, I suspect that your original data (unlike the XML sample you posted) uses namespaces. AFAICS that's the only possible reason why $xml.SelectSingleNode('//Arguments')would return an empty result.
XML files exported from the Windows Task Scheduler definitely are namespaced:
另外,我怀疑您的原始数据(与您发布的 XML 示例不同)使用名称空间。AFAICS 这是$xml.SelectSingleNode('//Arguments')返回空结果的唯一可能原因。从 Windows 任务计划程序导出的 XML 文件肯定是命名空间的:
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task??">
<!-- ... -->
</Task>
Namespaces are not like other node attributes and affect not only the node itself, but also its child nodes. For selecting nodes from an XML with namespaces you need a namespace manager:
命名空间与其他节点属性不同,不仅会影响节点本身,还会影响其子节点。要从具有命名空间的 XML 中选择节点,您需要一个命名空间管理器:
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace('ns', $xml.DocumentElement.NamespaceURI)
$element = $xml.SelectSingleNode('//ns:Arguments', $nsm)
回答by Dave_J
When I run:
当我运行时:
$filePathToTask = "C:\temp\Task.xml"
$xml = New-Object XML
$xml.Load($filePathToTask)
$element = $xml.SelectSingleNode("//Arguments")
$element.InnerText = "New Text"
$xml.Save($filePathToTask)
And re-check the output, I do see the updated value:
并重新检查输出,我确实看到了更新的值:
<Task>
<Settings>
</Settings>
<Actions Context="Author">
<Exec>
<Command>blablabla</Command>
<Arguments>New Text</Arguments>
</Exec>
</Actions>
</Task>
I enclosed the path in quotes, otherwise I was getting an error on the load line. That's good practice anyway, since the parameter for the Load method takes string filepathas input. Then as Ansgar mentions, use the assignment operator ("=") to set the new value in memory, then dump to file.
我用引号将路径括起来,否则我在加载线上遇到错误。无论如何,这是一个很好的做法,因为 Load 方法的参数将字符串文件路径作为输入。然后正如 Ansgar 所提到的,使用赋值运算符(“=”)在内存中设置新值,然后转储到文件。

