如何使用PowerShell编辑和保存XML节点

时间:2017-09-25 20:09:48

标签: xml powershell

我似乎无法让这个工作。我想使用PowerShell选择特定类型的所有节点,编辑它们,然后保存回磁盘。

以下是起始XML文件:

<Cars>
  <Car>Car1</Car>
  <Car>Car2</Car>
</Cars>

以下是修改后的文件:

<Cars>
  <Car Text="Car1"></Car>
  <Car Text="Car2"></Car>
</Cars>

尝试过:

[xml]$xaml = Get-Content -Path "C:\Test\TranslationUtility\cars.xml" |
             Select-Xml -XPath "//Car" |
             Write-Host $_.InnerText;

3 个答案:

答案 0 :(得分:1)

您需要遍历管道中的结果。搜索汽车有多个结果。最后,您需要% {$_.Node.Text}而不是Write-Host $_.InnerText;

%For-Each Object的快捷方式。因此它基本上遍历每个条目并显示您需要的信息。

答案 1 :(得分:1)

以下是我如何处理这个问题。

首先,您从xml文件中获取内容,然后使用SelectNodes查找所需的节点,迭代它们,创建属性并分配值。

完成此操作后,剩下的就是将xml保存回来。

[xml]$MyXML = Get-Content 'C:\__tmp\YourXmlFile.xml'

$Cars  = $MyXML.SelectNodes('//Car')

$Cars | foreach {
$TextAttrib = $_.OwnerDocument.CreateAttribute('text') 
$_.Attributes.Append($TextAttrib) |Out-Null;
$_.SetAttribute('text','My Car text...')
}

$MyXML.Save('C:\__tmp\YourXmlFile.xml')

正如您所看到的,我只会写一个静态文本,我的汽车文字...... ,但您可以根据自己的需要定制。

答案 2 :(得分:1)

您发布的代码应该抛出一堆错误,因为Get-Content(没有参数-Raw)会产生一个字符串数组,每个字符串本身都是无效的XML。将其提供到Select-Xml不起作用。此外,您使用[xml]类型加速器和Write-Host是错误的。

经验法则:

  • 如果您想使用Select-Xml,请让它自行读取文件(通过其-Path参数):

    $xpath   = '//Car'
    $xmlfile = 'C:\Test\TranslationUtility\cars.xml'
    
    Select-Xml -Xpath $xpath -Path $xmlfile
    
  • 如果您想使用Get-Content[xml]类型加速器,请使用SelectNodes()方法:

    $xpath   = '//Car'
    $xmlfile = 'C:\Test\TranslationUtility\cars.xml'
    
    [xml]$xml = Get-Content $xmlfile
    $xml.SelectNodes($xpath)
    

但是,仅此一项不允许您实现所需的结果,因为您想要操作XAML文件。请不要忽略您的问题中的重要信息。我只是知道,因为当你删除它时我只是回应你之前的问题。

XAML文件总是使用命名空间,因此您必须使用命名空间管理器来处理它,如下所示:

$xpath   = '//ns:Car'
$xmlfile = 'C:\Test\TranslationUtility\cars.xml'
$ns      = @{'ns' = 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'}

Select-Xml -Xpath $xpath -Path $xmlfile -Namespace $ns

或者像这样:

$xpath   = '//ns:Car'
$xmlfile = 'C:\Test\TranslationUtility\cars.xml'

[xml]$xml = Get-Content $xmlfile

$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace("ns", $xml.DocumentElement.NamespaceURI)

$xml.SelectNodes($xpath, $nsm)

由于你想要修改XML数据,我可能会采用后一种方法。这允许您添加如下属性:

$i = 1
$xml.SelectNodes($xpath, $nsm) | ForEach-Object {
    [void]$_.SetAttribute('Text', "Car$i")
    $i++
}

通过Save()方法保存修改后的XML:

$xml.Save('C:\path\to\output.xml')