繁体   English   中英

使用 PowerShell 遍历到 xml 节点

[英]Traverse into xml nodes using PowerShell

在这个 xml 中,我必须过滤与我的 stringArray $myStringArray 匹配的标签<controlTask> id 值(使用 powershell)

如果匹配,则遍历它并找到<myflow:eventBooster>event="start"并将脚本内容替换$startContent1 ,并找到event="end"替换为$endContent1

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:myflow="http://myflow.google.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="POC">
   <thread id="JALSA_KUSHI_ONLY" name="JALSA ONLY" isFine="true" myflow:isOk="true">
      <docprocess>My Doc Process</docprocess>
      <extensionElements>
         <myflow:historyLevel><![CDATA[audit]]></myflow:historyLevel>
      </extensionElements>
      <controlTask id="ReadDoc1" name="Read Doc" myflow:type="http">
         <extensionElements>
            <myflow:field name="rnhAsJson">
               <myflow:string><![CDATA[true]]></myflow:string>
            </myflow:field>
            <myflow:eventBooster event="start" class="org.abc.SecureJavascripteventBooster">
               <myflow:scriptInfo scriptType="javascript" script="&quot;use strict&quot;;var loaded={require:require,exports:{}};" />
            </myflow:eventBooster>
            <myflow:eventBooster event="end" class="org.abc.SecureJavascripteventBooster">
               <myflow:scriptInfo scriptType="javascript" script="&quot;use strict&quot;;var loaded={require:require,exports:{}},pending={};function require(e,t){define(void 0,e,t)};" />
               <myflow:field name="language">
                  <myflow:string><![CDATA[javascript]]></myflow:string>
               </myflow:field>
            </myflow:eventBooster>
         </extensionElements>
      </controlTask>
      <JimmyGate id="MyWish" name="My own" />
      <controlTask id="WriteDoc1" name="write task" myflow:type="http">
         <extensionElements>
            <myflow:field name="requestMethod">
               <myflow:string><![CDATA[POST]]></myflow:string>
            </myflow:field>
            <myflow:eventBooster event="start" class="org.abc.SecureJavascripteventBooster">
               <myflow:scriptInfo scriptType="javascript" script="&quot;use strict&quot;;" />
            </myflow:eventBooster>
            <myflow:eventBooster event="end" class="org.abc.SecureJavascripteventBooster">
               <myflow:scriptInfo scriptType="javascript" script="&quot;use strict&quot;;var loaded={require:require}" />
            </myflow:eventBooster>
         </extensionElements>
      </controlTask>
      <JimmyGate id="sid-iquweiq-1uy1-8173eu-817e81ye" />
   </thread>
</definitions>

我有 controltaskId,但无法遍历它。 但是获取与<controlTask><myflow:eventBooster>匹配的所有数据

$xmldata =( Select-Xml -Path $location\xyz.xml -XPath / ).Node;

$controltaskId = $xmldata.definitions.thread.controlTask.GetAttribute("id");

有人可以在这里帮忙吗

这是一个可能的解决方案:

$xmldata.definitions.thread.controlTask.Where{ $_.id -in $myStringArray }.ForEach{
   $_.extensionElements.eventBooster.Where{ $_.event -eq 'start' }.ForEach{
       $_.scriptInfo.script = $startContent1
   }
   $_.extensionElements.eventBooster.Where{ $_.event -eq 'end' }.ForEach{
       $_.scriptInfo.script = $endContent1
   }
}
  • $xmldata.definitions.thread.controlTask 为我们提供了一个包含所有controlTask 元素的数组。 同样, $_.extensionElements.eventBooster为我们提供了当前extensionElements中所有eventBooster元素的数组。 请参阅成员访问枚举以了解其工作原理。
  • 使用 PowerShell 内在方法.Where{}过滤 arrays(或者使用Where-Object命令)。
    • 应用于.controlTask ,按$myStringArray中包含的id属性过滤。
    • 应用于.eventBooster ,过滤匹配event属性。
  • PowerShell 的内部方法.ForEach{}用于迭代过滤后的元素(或者使用ForEach-Object命令)。 内在方法的语法更简洁,它们比命令替代品执行得更好,所以我更喜欢它们来处理数据结构(而不是其他命令的 output)。

尝试以下操作:

using assembly System 
using assembly System.Linq
using assembly System.Xml.Linq 

$inputFilename = "c:\temp\test.xml"
$outputFilename = "c:\temp\test1.xml"
$xDoc = [System.Xml.Linq.XDocument]::Load($inputFilename)
$root = [System.Xml.Linq.XElement]$xDoc.Root
#Write-Host "root = " $root
$ns = [System.Xml.Linq.XNamespace]$root.GetNamespaceOfPrefix("myflow")
$eventBoosters = $xDoc.Descendants($ns + "eventBooster")
$starts = [System.Linq.Enumerable]::Where($eventBoosters, [Func[object,bool]]{ param($x) [string]$x.Attribute("event").Value -eq "start"})
foreach($start in $starts)
{
   [System.Xml.Linq.XElement]$start.SetAttributeValue("event", '$startContent1')
}
$ends = [System.Linq.Enumerable]::Where($eventBoosters, [Func[object,bool]]{ param($x) [string]$x.Attribute("event").Value -eq "end"})
foreach($end in $ends)
{
   [System.Xml.Linq.XElement]$end.SetAttributeValue("event", '$endContent1')
}
$xDoc.Save($outputFilename)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM