2017-09-25 46 views
1

我似乎无法得到此工作。我想使用PowerShell选择特定类型的所有节点,编辑它们,然后保存回磁盘。如何使用PowerShell编辑和保存XML节点

这里是开始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; 

回答

2

您发布的代码应该会引发一堆错误,因为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') 
+0

太谢谢你了。是的,我收到了像你提到的错误。以上工作很好。 –

1

您需要通过结果来迭代在管线中。你有多个搜索汽车的结果。最后,您需要% {$_.Node.Text}而不是Write-Host $_.InnerText;

%For-Each Object的快捷方式。所以它基本上循环每个条目并显示您需要的信息。

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') 

正如你所看到的,我的只写一个静态文本,我的车文字...,但你可以调整这个以满足您的需求。