问题描述
我需要向 XML 中的现有节点添加一个新元素。当前的结构基本上是这样的:
<CommandManagerResults>
<ListReports>
<Row>
<Name>aaa</Name>
</Row>
<Row>
<Name>bbb</Name>
</Row>
</ListReports>
<ListDocuments>
<Row>
<Name>ccc</Name>
</Row>
<Row>
<Name>ddd</Name>
</Row>
</ListDocuments>
</CommandManagerResults>
$directory = "E:\temp"
cd $directory
[xml]$XmlDocument = Get-Content ".\test.xml"
$ProjectName = $XmlDocument.CreateElement("ProjectName")
$ProjectName.InnerText = "test"
$temp = $XmlDocument.SelectNodes("//Row")
foreach ($row in $temp){
$row.AppendChild($ProjectName)
$XmlDocument.Save($directory + '\test.xml')
}
但是,只有最后一个“行”节点会与新的“项目名称”元素一起保存。我添加了 '$row | FL' 在 foreach 循环中,它显示每个 Row 都具有 ProjectName 元素,因为它在循环的每次迭代中都存在,不幸的是,无论我是在 foreach 循环内部还是在 foreach 循环之后保存,只有最后一个 Row 节点与 ProjectName 元素一起保存。它是如何出来的:
<CommandManagerResults>
<ListReports>
<Row>
<Name>aaa</Name>
</Row>
<Row>
<Name>bbb</Name>
</Row>
</ListReports>
<ListDocuments>
<Row>
<Name>ccc</Name>
</Row>
<Row>
<Name>ddd</Name>
<ProjectName>Test</ProjectName>
</Row>
</ListDocuments>
</CommandManagerResults>
我希望结构最终是什么样子:
<CommandManagerResults>
<ListReports>
<Row>
<Name>aaa</Name>
<ProjectName>Test</ProjectName>
</Row>
<Row>
<Name>bbb</Name>
<ProjectName>Test</ProjectName>
</Row>
</ListReports>
<ListDocuments>
<Row>
<Name>ccc</Name>
<ProjectName>Test</ProjectName>
</Row>
<Row>
<Name>ddd</Name>
<ProjectName>Test</ProjectName>
</Row>
</ListDocuments>
</CommandManagerResults>
仅供参考,Powershell 和 XML 非常新,所以希望我所说的一切都有意义,而且我至少正朝着正确的道路前进。
解决方法
您必须为要添加的每个元素创建一个新元素。最后,Save()
调用应仅在您完成文档后才进行。
$temp = $XmlDocument.SelectNodes("//Row")
foreach ($row in $temp){
$ProjectName = $XmlDocument.CreateElement("ProjectName")
$ProjectName.InnerText = "test"
$row.AppendChild($ProjectName)
}
$XmlDocument.Save($directory + '\test.xml')
顺便说一句,[xml]$XmlDocument = Get-Content ".\test.xml"
虽然很方便,但却是不好的做法。它只是偶然工作,因为现在大多数 XML 文档都是 UTF-8 编码的,这恰好是 Get-Content
使用的默认编码。但是 Get-Content
对 XML“编码”属性的实际值一无所知。
加载 XML 文档的正确方法,同时尊重其“编码”属性:
$xml = [xml]::new()
$xml.Load((Convert-Path ".\test.xml"))