我不确定我在哪里出错了。我有以下PowerShell错误消息:
Exception setting "Value": "Cannot set a value on node type 'Document'." At line:18 char:5 + $XMLDoc.$controlSource='$replaceText' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], SetValueInvocationException + FullyQualifiedErrorId : CatchFromBaseAdapterSetValue
我的代码如下:
[xml]$XMLDoc = (Get-Content "C:\process.xml")
foreach($file in Get-ChildItem $outputDirectory) {
$replaceText = <tested working string of the value to replace in the XML doc>
$controlSource = $XMLDoc.SelectNodes("/beans/bean[@id='$bNode']/property[@name='configOverrideMap']/map/entry[@key='sfdc.extractionSOQL']/@value")
$XMLDoc.$controlSource = '$replaceText'
#$XMLDoc -replace ('^"$controlSource"$','^"$replaceText"$') | Out-File $XMLDoc
}
我正在尝试用字符串替换XML文件中的值,并将变量$XMLDoc
的内容写入文件C:\process.xml
,直到我收到上述消息。我可以得到关于将$XMLDoc
写入文件的部分,问题是我仍然无法获取我的字符串来替换变量并保存。我理解这可能很草率,因为我在foreach
循环中多次执行相同的任务,但我目前的目标是功能而不是最佳功能。
<beans>
<bean id="MenuGet">
<property name="name" />
<property name="MapOverride">
<map>
<entry key="node.infoblock" value="k4jk2jb54B$T45bt2j5ktb3B%$" />
</map>
</property>
</bean>
<bean id="SystemGet">
<property name="name" />
<property name="MapOverride">
<map>
<entry key="node.infoblock" value="b34t34bhj54b%B#Y$%Bn45ht5h" />
</map>
</property>
</bean>
</beans>
答案 0 :(得分:1)
您的代码存在3个问题:
$XMLDoc.SelectNodes()
返回节点集合。您不能在点访问语句($XMLDoc.$controlSource
)中使用它,并且您无论如何都不需要。只需删除$XMLDoc.
并循环遍历集合的元素。
您的XPath表达式选择value
个属性节点。但是,您无法直接为节点分配值。您必须将其分配给其Value
或#text
媒体资源。请注意,与Value
不同,属性#text
仅接受string类型的值。
您要分配的值是单引号字符串,因此PowerShell不会在其中展开变量$replaceText
。删除单引号。
这将做你想要的:
$xpath = "/beans/bean[@id='$bNode']/property[@name='MapOverride']/map/entry[@key='node.infoblock']/@value"
$XMLDoc.SelectNodes($xpath) | ForEach-Object {
$_.Value = $replaceText
}
答案 1 :(得分:1)
必须创建与问题中的示例XML略有不同的示例XML,以获得基于XPath的简短工作示例:
[xml]$XMLDoc= @'
<beans>
<bean id="MenuGet">
<property name="name" />
<property name="MapOverride">
<map>
<entry key="node.infoblock" value="k4jk2jb54B$T45bt2j5ktb3B%$" />
</map>
</property>
</bean>
<bean id="SystemGet">
<property name="name" />
<property name="MapOverride">
<map>
<entry key="node.infoblock" value="b34t34bhj54b%B#Y$%Bn45ht5h" />
</map>
</property>
</bean>
</beans>
'@;
一些简单的替换数据来模仿foreach
循环:
$replacements = @{
MenuGet = 'MenuGet-REPLACE';
SystemGet = 'SystemGet-REPLACE';
};
这里有一些测试/工作示例代码:
foreach($bNode in $replacements.Keys)
{
$replaceText= $replacements.$bNode;
$controlSource = $XMLDoc.SelectSingleNode(
"/beans/bean[@id='$bNode']/property[@name='MapOverride']/map/entry[@key='node.infoblock']/@value"
);
$controlSource.Value = $replaceText;
}
$XMLDoc.OuterXml;
# $XMLDoc.Save($OUT_PATH);