我有如下所示的XML:
<config>
<backup>
<environment>
<server name="exampleserver2" type="FM">
<utility hfmcopyapp="C:\Oracle\Middleware\EPMSystem11R1\products\FinancialManagement\Utilities\HfmCopyAppCmd_x64.exe"/>
<utility lcm="C:\Oracle\Middleware\user_projects\FM1\bin\Utility.bat"/>
</server>
</environment>
</backup>
</config>
我正在使用的PowerShell代码(已更新,反映了工作代码):
function Get-ServerAttrByXmlTag
{
[OutputType([string])]
param
(
[Parameter(Mandatory = $true)]
[string]$server,
[string]$type,
[string]$feature,
[string]$xmltag,
[string]$attribute
)
if ($type)
{
$Value = $xmlDoc.SelectSingleNode("//server[@name='$server' and @type='$type']/$xmltag/@$attribute").'#text'
}
else
{
$Value = $xmlDoc.SelectSingleNode("//server[@name='$server']/$xmltag/@$attribute").'#text'
}
$Value
}
我得到的错误是非终止的,并且该函数能够找到该属性。只是元素<utility>
的第一次迭代不包含属性lcm
,所以会引发以下错误:
ERROR: Select-Object : Property "lcm" cannot be found. Common.ps1 (114, 5): ERROR: At Line: 114 char: 5 ERROR: + Select-Object -ExpandProperty $attribute ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ERROR: + CategoryInfo : InvalidArgument: (utility:PSObject) [Select-Object], PSArgumentException ERROR: + FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand ERROR:
每当有多个<utility>
节点时(如果第一个节点不包含$atttribute
),我正在寻找一条错误记录。最终它将找到utility.lcm
路径,但不会抛出错误。
例如,如果我要寻找utility.lcm
,则第一个实用程序节点不是lcm
,而是hfmcopyapp
。由于未找到lcm
,因此引发了错误。
如何在不引发错误的情况下选择正确的节点/属性?
也没有重新排列XML。它必须使用给定的节点属性。
答案 0 :(得分:1)
我几乎总是建议通过点访问使用SelectNodes()
或SelectSingleNode()
和XPath expression,除了极少数例外。
要选择具有特定属性的节点,请使用谓词检查该属性的存在:
$xml.SelectNodes('//utility[@lcm]')
仅选择属性,请选择属性元素而不是其节点:
$xml.SelectNodes('//utility/@lcm')
如果您需要将更多过滤条件应用于祖先节点,也可以这样做:
$xml.SelectNodes("//server[@name='$server' and @type='$type']/utility/@lcm")