PowerShell管道和xpath查询

时间:2018-01-02 11:15:57

标签: powershell xpath pipe

我在使用管道时遇到了一些问题。这就是我所做的:

[xml]$y= (gc alpha.xml)
[xml]$p_v = (gc beta.xml)
$b=$x.report.row[1].ELEMENT_ID
$y.SelectNodes("//report/row[elementRootID/text()='$b']").pID|
    %{
        if ($p_v.SelectNodes("//report/row[id/text()='$_']").obpdID = $NULL)
            {write "Hurra!"}}

,其中alpha.xml看起来像

<report>
<row>
<pID>418</pID>
<elementRootID>63789</elementRootID>
</row>
</report> 

和beta.xml有点像:

<report>
<row>
<ID>418</ID>
<obpdID>248</obpdID>
</row>
</report> 

当我这样做时,powershell没有在row-tag中找到属性obpdID。如果我直接输入它,那么它正在工作。如果有人能给我一个暗示这里出了什么问题的话会很棒。提前谢谢。

3 个答案:

答案 0 :(得分:3)

您的代码不起作用,因为您使用的=应该使用-eq,即

if ($p_v.SelectNodes("//report/row[id/text()='$_']").obpdID = $NULL)

应该是

if ($p_v.SelectNodes("//report/row[id/text()='$_']").obpdID -eq $NULL)

但是为了更完整的答案/更好的[IMO]做事,你应该采用以下方法。

因为.... XPath是icky ... PowerShell是王牌!

[xml]$alpha = @"
<report>
    <row>
        <pID>418</pID>
        <elementRootID>63789</elementRootID>
    </row>
</report>
"@

[xml]$beta = @"
<report>
    <row>
        <ID>418</ID>
        <obpdID>248</obpdID>
    </row>
    <row>
        <ID>419</ID>
        <obpdID>249</obpdID>
    </row>
</report> 
"@

# Because our object is of [xml] type, we can just naigate the DOM directly without XPath!
$alpha_pID           = $alpha.report.row.pID
$alpha_elementRootID = $alpha.report.row.elementRootID

# And because it's an object; we can use all our lovely PS CmdLets instead, too!
$beta_obpdID = ($beta.report.row | Where-Object ID -EQ $alpha_pID).obpdID

# Results
$alpha_pID
$beta_obpdID

@OP

的奖金

给出代码中的初始ElementRootID($b;我的$elementRootID) - 在$alpha中找到匹配的记录然后找到相关的结果匹配$beta并将它们作为单个对象返回。

[xml]$alpha = @"
<report>
    <row>
        <pID>418</pID>
        <elementRootID>63789</elementRootID>
    </row>
    <row>
        <pID>419</pID>
        <elementRootID>63789</elementRootID>
    </row>
</report>
"@

[xml]$beta = @"
<report>
    <row>
        <ID>418</ID>
        <obpdID>248</obpdID>
    </row>
    <row>
        <ID>419</ID>
        <obpdID>249</obpdID>
    </row>
</report> 
"@

$elementRootID = 63789

$results = $alpha.report.row |
    Where-Object elementRootID -EQ $elementRootID |
    ForEach-Object {
        $beta.report.row |
            Where-Object ID -EQ $_.pID |
            Select-Object -Property @{Name="elementRootID"; Expression={$elementRootID}}, @{Name="pID"; Expression={$_.ID}}, obpdID
    }

$results

结果

elementRootID pID obpdID
------------- --- ------
        63789 418 248   
        63789 419 249   

答案 1 :(得分:0)

采用非xpath解决方案:

($y.report.row | Where-Object elementRootID -EQ $b).pID |
%{
    if (($p_v.report.row | Where-Object id -eq $_).obpdID -eq $NULL)
    {$PG_ID = $_}
    else{$PG_ID = ($p_v.report.row | Where-Object id -eq $_).obpdID}
}

答案 2 :(得分:-1)

XPath区分大小写。这应该有效:

if ($p_v.SelectNodes("//report/row[ID/text()='$_']").obpdID -eq $NULL)

但正如gvee所说,在PowerShell中使用内置的xml功能要容易得多。