【问题标题】:How do I alter XML with PowerShell/XPath and save the document?如何使用 PowerShell/XPath 更改 XML 并保存文档?
【发布时间】:2010-12-15 17:20:54
【问题描述】:

我希望使用 PowerShell 来更改 XML。我无法使用 XPath 复制 XML。我可以加载 XML,但我不知道如何使用 XPath 列出 XML 并使用我检索的内容创建另一个 XML 文件。

$doc = new-object "System.Xml.XmlDocument"
$doc.Load("XmlPath.xml")

另外,如何将删除的 XML 添加到另一个 XML 文件中?

【问题讨论】:

  • 请注意 - 您可以像这样简单地加载 xml 文档:$doc = [xml](get-content xmlpath.xml) 或 $doc = [xml](gc xmlpath.xml)跨度>

标签: xml powershell xpath


【解决方案1】:

如果您使用的是 PowerShell 2.0,则可以使用新的 Select-Xml cmdlet 根据 XPath 表达式选择 xml,例如:

$xml = '<doc><books><book title="foo"/></books></doc>'
$xml | Select-Xml '//book'
Node    Path          Pattern
----    ----          -------
book    InputStream   //book

移除节点:

PS> $xml =[xml]'<doc><books><book title="foo"/><book title="bar"/></books></doc>'
PS> $xml | Select-Xml -XPath '//book' | 
        Foreach {$_.Node.ParentNode.RemoveChild($_.Node)}

title
-----
foo
bar

PS> $xml.OuterXml
<doc><books></books></doc>

然后保存到文件:

$xml.Save("$pwd\foo.xml")
Get-Content foo.xml
<doc>
  <books>
  </books>
</doc>

【讨论】:

  • 当我只做 $xml | select-xml -xpath 'xpath' 我没有得到任何输出。什么被输送到 foreach 中。我没有关注选择正在做什么。有没有一种简单的方法可以替换某个 xpath 位置的值?谢谢
  • 您是否正在使用 PowerShell 社区扩展?如果是 PSCX,那么我相信它是 XPathNavigator,但如果您使用的是 PowerShell 2.0 Select-Xml,它是他们创建的具有 Node 属性的自定义对象。
  • 不,我没有使用 powershell 社区扩展。你是说 $xml | select-xml -xpath '//Configuration/ConfigXML/Configuration/DiscoveryHandlers' 应该可以吗?好吧,它不适合我。我放的 xpath 似乎不起作用。有任何想法吗?感谢所有的帮助。
  • Keith 发布的示例代码对我有用,您确定您的 XML 和 XPath 正确吗?可以使用诸如 pgfearo.googlepages.com/home 之类的工具来检查您的 XPath 与您的 XML。
  • Bruce,您的 XML 文档是否使用 XML 命名空间?如果是这样,则必须调整 XPath 查询,并且您必须通过 -Namespace 参数向 Select-Xml 提供名称空间映射。如果是这样,我可以为您提供一个使用 XML 命名空间的示例。
【解决方案2】:

加载 Linq Xml 程序集:

[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq")
[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.XPath")

加载你的xml(注意,你可以使用::Load("file")而不是::Parse(...)从文件加载:

$xml = [System.Xml.Linq.XDocument]::Parse("<root> <row>Hey</row> <row>you</row> </root>")

修改(在本例中删除第一行:

[System.Xml.XPath.Extensions]::XPathSelectElement($xml, "//row").Remove()

保存到文件:

$xml.Save("MyXml.xml")

使用 System.Xml(而不是 System.Xml.Linq):

$doc = new-object "System.Xml.XmlDocument"
$doc.Load("MyXml_int.xml")

$node = $doc.SelectSingleNode("//row");
$node.ParentNode.RemoveChild($node)

$doc.Save("MyXml_out.xml")

【讨论】:

  • 我正在做这部分服务器加载应用程序并更改这些应用程序的配置文件。如果可能的话,我不想加载另一个程序集。有没有办法用普通的powershell做到这一点?谢谢
  • Bruce227,我使用 System.Xml 添加了示例。
  • 您好,nestor,我尝试了您的 system.xml,但没有成功。 “//row”是xpath值吗?如果是这样,当我使用我生成的 xpath 时,我只是得到一个空值。谢谢
  • "//row" 与 Xml "Heyyou" 一起使用。您需要将其更改为适合您的 xml 的任何 xpath。我在我的机器上尝试了我的示例,它成功了。
  • 您好,我看过的 xpath 示例似乎没有 // 只有 / 代表根目录,然后是路径。
猜你喜欢
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2010-11-06
相关资源
最近更新 更多