我有一个Xml文件,其中包含如下所示的节点:
<Installation>
<VersionData Type="Upgrade"
</VersionData>
<DeploymentData>
<DataFileGroup enable="True">
<DataFileItem name="file2.exe.config" enable="True" installMode="Both" sourceFolder="C:\files\" distributionType="AddReplace" >
<ItemTarget featureName="AppServer" targetPaths="$targetPath/folder3;"/>
<ItemTarget featureName="WebServer" targetPaths="$targetPath/folder1;"/>
<ItemTarget featureName="DBServer" targetPaths="$targetPath;"/>
</DataFileItem>
</DataFileGroup>
</DeploymentData>
</Installation>
$xmlFile = "C:\work\myXML.xml"
$xml = [xml](Get-Content $xmlFile)
$xml.Load($xmlFile)
首先,我需要获取featureName为DBServer
的targetPaths的值。
然后我要更改的值:
ItemTarget featureName="DBServer" targetPaths="$targetPath;"
到
ItemTarget featureName="DBServer" targetPaths="$targetPath;$concate_TargetPath"
答案 0 :(得分:2)
首先,您需要通过更改来修正XML
<VersionData Type="Upgrade"
</VersionData>
到
<VersionData Type="Upgrade" />
拥有有效的xml文件后,您可以执行以下操作来更新属性值:
$xmlFile = "C:\work\myXML.xml"
[xml]$xml = Get-Content $xmlFile -Raw
# find all nodes 'ItemTarget' with featureName 'DBServer'
$nodes = $xml.SelectNodes("//ItemTarget[@featureName='DBServer']")
foreach ($node in $nodes) {
# change the value of the 'targetPaths' attribute
# because of the dollar signs, use single quotes here if this should be the literal value.
# if you mean to have these values expanded from variables with these names, use double quotes
$node.targetPaths = '$targetPath;$concate_TargetPath'
}
# save the changes to a new xml file
$xml.Save('C:\work\myXML_Updated.xml')
从您的评论中,我了解到的内容远不止原始问题中的内容。
如果只需要更改节点targetPaths
中ItemTarget
个节点的DataFileItem
属性,该节点的属性为name
,其值等于a特定值, THEN ,targetPaths
属性需要通过向其添加新路径来更改,如果,该新路径尚不存在。
(到目前为止,我是否正确?)
在这种情况下,请尝试以下操作:
# this is the name attribute to search for the DataFileItem node
$dataFileName = "file2.exe.config"
# this is the path to add to the 'targetPaths' attribute if not already present
$newPath = "SomeNewPathToAppend"
$xmlFile = 'C:\work\myXML.xml'
[xml]$xml = Get-Content $xmlFile -Raw
# find all nodes 'ItemTarget' with featureName 'DBServer' within the 'DataFileItem' node that has attribute $dataFileName
$nodes = $xml.SelectNodes("//DataFileItem[@name='$dataFileName']/ItemTarget[@featureName='DBServer']")
foreach ($node in $nodes) {
# split the current value by the semicolon and remove empty elements
$paths = $node.targetPaths.Split(";", [System.StringSplitOptions]::RemoveEmptyEntries)
# check if the $newPath is not already in this array
if ($paths -notcontains $newPath) {
# change the value of the 'targetPaths' attribute by adding the $newPath to it
$paths += $newPath
$node.targetPaths = "{0};" -f ($paths -join ';')
}
}
# save the changes to a new xml file
$xml.Save('C:\work\myXML_Updated.xml')
由于上述代码使用区分大小写的XPath查找要更新的节点,因此它无法处理应以不区分大小写的方式比较任何name
或featureName
的情况。
因此,这是一种新方法,可通过不区分大小写的比较为您提供要更新的项目:
# this is the name attribute to search for the DataFileItem node
$dataFileName = "file2.exe.config"
# this is the path to add to the 'targetPaths' attribute if not already present
$newPath = "SomeNewPathToAppend"
$xmlFile = 'C:\work\myXML.xml'
[xml]$xml = Get-Content $xmlFile -Raw
# find all 'DataFileItem' nodes that have attribute 'name' equal to $dataFileName (case insensitive)
$nodes = $xml.GetElementsByTagName("DataFileItem") | Where-Object { $_.name -eq $dataFileName }
# or do it like this:
# $nodes = $xml.ChildNodes.DeploymentData.DataFileGroup.DataFileItem | Where-Object { $_.name -eq $dataFileName }
# within these 'DataFileItem' nodes, find all 'ItemTarget' elements where attribute 'featureName' equals "DBServer" (case insensitive)
$nodes.ItemTarget | Where-Object { $_.featureName -eq "DBServer" } | ForEach-Object {
# split the current value by the semicolon and remove empty elements
$paths = $_.targetPaths.Split(";", [System.StringSplitOptions]::RemoveEmptyEntries)
# check if the $newPath is not already in this array
if ($paths -notcontains $newPath) {
# change the value of the 'targetPaths' attribute by adding the $newPath to it
$paths += $newPath
$_.targetPaths = "{0};" -f ($paths -join ';')
}
}
# save the changes to a new xml file
$xml.Save('C:\work\myXML_Updated.xml')