如何更新System.Xml.XmlDocument中的节点值?

如何更新System.Xml.XmlDocument中的节点值?,xml,powershell,xpath,Xml,Powershell,Xpath,在PowerShell v3中,我创建了如下XmlDocument对象: [System.Xml.XmlDocument]$xmldoc = new-object System.Xml.XmlDocument $xmldoc.Load($xmlfile) $xmldoc.Save($xmlfile) <?xml version="1.0" encoding="UTF-16"?> <Task version="1.4" xmlns="http://schemas.micros

在PowerShell v3中,我创建了如下XmlDocument对象:

[System.Xml.XmlDocument]$xmldoc = new-object System.Xml.XmlDocument
$xmldoc.Load($xmlfile)
$xmldoc.Save($xmlfile)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Author>MYDOMAIN\user.name</Author>
    <Description>my description</Description>
  </RegistrationInfo>
  <Triggers>
    <TimeTrigger>
      <Repetition>
        <Interval>PT2M</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2015-09-18T09:29:14</StartBoundary>
      <Enabled>true</Enabled>
      <RandomDelay>PT3S</RandomDelay>
    </TimeTrigger>
  </Triggers>
...
$ns = @{'ns'='http://schemas.microsoft.com/windows/2004/02/mit/task'}
$xml = Select-Xml -Xml $xmldoc -XPath "//ns:Task/ns:Triggers/ns:TimeTrigger/ns:StartBoundary" -Namespace $ns
$xml.Node.Value = $newvalue
经过一些处理后,我想让用户更新
$xmlfile
中节点的值

给定要分配的节点名称和新值,如何更新
$xmldoc

$node = StartBoundry
$newvalue = StringValue
我知道我可以这样存钱:

[System.Xml.XmlDocument]$xmldoc = new-object System.Xml.XmlDocument
$xmldoc.Load($xmlfile)
$xmldoc.Save($xmlfile)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Author>MYDOMAIN\user.name</Author>
    <Description>my description</Description>
  </RegistrationInfo>
  <Triggers>
    <TimeTrigger>
      <Repetition>
        <Interval>PT2M</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2015-09-18T09:29:14</StartBoundary>
      <Enabled>true</Enabled>
      <RandomDelay>PT3S</RandomDelay>
    </TimeTrigger>
  </Triggers>
...
$ns = @{'ns'='http://schemas.microsoft.com/windows/2004/02/mit/task'}
$xml = Select-Xml -Xml $xmldoc -XPath "//ns:Task/ns:Triggers/ns:TimeTrigger/ns:StartBoundary" -Namespace $ns
$xml.Node.Value = $newvalue
原始XML如下所示:

[System.Xml.XmlDocument]$xmldoc = new-object System.Xml.XmlDocument
$xmldoc.Load($xmlfile)
$xmldoc.Save($xmlfile)
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Author>MYDOMAIN\user.name</Author>
    <Description>my description</Description>
  </RegistrationInfo>
  <Triggers>
    <TimeTrigger>
      <Repetition>
        <Interval>PT2M</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2015-09-18T09:29:14</StartBoundary>
      <Enabled>true</Enabled>
      <RandomDelay>PT3S</RandomDelay>
    </TimeTrigger>
  </Triggers>
...
$ns = @{'ns'='http://schemas.microsoft.com/windows/2004/02/mit/task'}
$xml = Select-Xml -Xml $xmldoc -XPath "//ns:Task/ns:Triggers/ns:TimeTrigger/ns:StartBoundary" -Namespace $ns
$xml.Node.Value = $newvalue
但如果我只有节点名,如何获取路径?是否有一种方法可以做到这一点,或者我必须迭代所有元素,直到找到匹配的节点名?

将XPath修改为:

$node = 'StartBoundary'
$xmlInfo = Select-Xml -Xml $xmldoc -XPath "//ns:$node" -Namespace $ns
$xmlInfo.Node.Value = $newvalue

这似乎起作用了

[System.Xml.XmlDocument]$xmldoc =  New-Object System.Xml.XmlDocument
$xmldoc.Load($xmlfile)
# user selects node, provides $newvalue
[System.Xml.XmlNode]$xmlnode = $xmldoc.GetElementsByTagName($node)[0].ChildNodes[0]
$xmlnode.InnerText = $newvalue
$xmldoc.Save($xmlfile)

考虑到提供的唯一信息是标记名,您可以使用XPath
后代或self
轴(
/
)和
name()
-或
local-name()
-匹配XML文档中任意位置的目标元素:

$xmlInfo = Select-Xml -Xml $xmldoc -XPath "//*[name()='StartBoundary']"

这就是我正在做的实验。我还没有测试过,但我认为它应该可以工作。问题是为
-Xpath
组合字符串。。。这就是为什么我在寻找一个不需要路径或提供路径的方法的解决方案。因此,是的,
“//ns:$node”
“//*[name()='StartBoundary']]”
之间没有真正的区别,而后者不需要名称空间。此外,上面的帖子确实构成了xpath。在
$node
中输入所需的元素名,XPath表达式将找到它。与
'StartBoundary'
中的硬编码相反,我不需要完整路径。我想那根弦毕竟不难谱写。我发现这篇介绍很有帮助:完整的XPath规范如下: