【问题标题】:Selecting XML when there are multiple nodes with different attributes当有多个具有不同属性的节点时选择 XML
【发布时间】:2018-07-09 17:36:16
【问题描述】:

我的 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
}

我得到的错误是非终止的,函数能够找到属性。只是元素&lt;utility&gt;的第一次迭代没有包含lcm的属性,所以会抛出这个错误:

错误:选择对象:找不到属性“lcm”。 Common.ps1 (114, 5): 错误:在行:114 字符:5 错误:+ 选择对象 -ExpandProperty $attribute 错误:+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 错误:+ CategoryInfo : InvalidArgument: (utility:PSObject) [Select-Object], PSArgumentException 错误:+ FullyQualifiedErrorId:ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand 错误:

只要有多个&lt;utility&gt; 节点,如果第一个节点不包含$atttribute,我正在寻找的错误记录就会抛出。它最终会找到utility.lcm 路径,但并非没有抛出错误。

例如,如果我要查找utility.lcm,第一个实用程序节点不是lcm,而是hfmcopyapp。所以会抛出一个错误,因为没有找到lcm

如何选择正确的节点/属性而不引发错误?

也没有重新排列 XML。它必须与给定的节点属性一起工作。

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    我几乎总是建议使用 SelectNodes()SelectSingleNode()XPath expression 而不是点访问,很少有例外。

    要选择具有特定属性的节点,请使用检查该属性是否存在的谓词:

    $xml.SelectNodes('//utility[@lcm]')
    

    如果只选择属性,请选择属性元素而不是其节点:

    $xml.SelectNodes('//utility/@lcm')
    

    如果您需要对祖先节点应用更多过滤条件,您也可以这样做:

    $xml.SelectNodes("//server[@name='$server' and @type='$type']/utility/@lcm")
    

    【讨论】:

    • 我可以做类似 $Value = $xmlDoc.SelectNodes("//config.$feature.environment.server[@name='$server' and @type='$type']/ $xmltag/@$attribute")
    • 应该是$Value = $xmlDoc.SelectNodes("//config/$feature/environment/server[@name='$server' and @type='$type']/$xmltag/@$attribute").'#text',但是是的,应该可以。但是,如果您确实需要做类似的事情,我非常怀疑您正面临X-Y problem
    • 是的,我可能确实患有 X-Y 问题,而且我说得太早了。我仍然面临被放入错误记录中的相同错误消息。我会整理的。感谢您的帮助。
    • 我更新了powershell代码以反映函数的当前状态
    • @todd1215 不能在 XPath 表达式中使用点表示法。 //config.$feature.environment.server[...] 将查找不存在的节点 &lt;config.backup.environment.server&gt;。请再看看我的第一条评论。表达式中的节点名称必须用斜杠分隔。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多