在特定节点之后添加XML

时间:2017-09-22 09:38:46

标签: xml linq powershell

我已将以下XML文档作为XElement($el)加载:

<a>
    <b></b>
    <c></c>
    <d></d>
    <e></e>
</a>

如何使用PowerShell在$theElement下附加另一个XElement(<c></c>)?我尝试了以下方法:

$where = {
    param ($item)
    return ($item.Name.LocalName -eq "c")
}

$el.Descendants().Where($where).FirstOrDefault().Add($theElement)

但是出错了:

  

方法调用失败,因为[System.Collections.ObjectModel.Collection`1 [[System.Management.Automation.PSObject,System.Management.Automation,Version = 3.0.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35]]]不包含名为'FirstOrDefault'的方法。

注意:$el$theElement必须是System.Xml.Linq.XElement个对象。

1 个答案:

答案 0 :(得分:3)

你的问题是PowerShell相当困在.Net 1.1黑暗时代。

  • 没有扩展方法。 Linq中没有任何东西可以轻松实现,你必须将它们称为静态方法。
  • XmlDocument是一流的,(XDocument不是 - 为什么麻烦,因为扩展方法不起作用)

function validateCredit(){ var credit = $("#payment option[value='credit card']"); var paypal = $("#payment option[value='paypal']"); var bitcoin = $("#payment option[value='bitcoin']"); isCreditIssue = false; if (credit.prop('selected'){ errorCC = validateCC(); errorZip = validateZip(); errorCVV = validateCVV(); if ((errorCC) || (errorZip) || (errorCVV)){ isCreditIssue = true; console.log('credit issue'); } } else if (bitcoin.prop('selected')){ console.log('bitcoin'); isCreditIssue = false; } else if (paypal.prop('selected'){ console.log('paypal'); isCreditIssue = false; } return isCreditIssue; } 是一种扩展方法,因此它在PowerShell中根本不存在,您必须调用FirstOrDefault ...并且[System.Linq.Enumerable]::FirstOrDefault(方法不是&{ #39;来自Linq的那个,它是PowerShell的特定添加,所以你需要用它来做Where事。

TL; DR

你需要写这样的东西(First是因为当你告诉[0]只返回一个项目时,它会返回一个项目的数组):

Where

正常的PowerShell方式是使用XmlDocument和XPath:

给定$el.Descendants.Where({ $_.Name.LocalName -eq "c" }, 1)[0].Add($theElement) $xml以及XPath选择器:

$node

您可以使用PowerShellGallery中的Xml模块:

[xml]$xml = "
<a>
    <b></b>
    <c></c>
    <d></d>
    <e></e>
</a>
"

$node = "<k/>"

$selector = "//c"

或者你可以手写:

# Insert <k> after <c> in the $xml XmlDocument
$xml | Update-Xml -After //c $node