如何遍历来自XML的System.Array类型对象?

时间:2018-04-19 19:17:01

标签: xml powershell powershell-v2.0

我是解析XML的Powershell脚本的新手,我遇到了一个需要确保在另一行之前严格执行XML行的情况。

为了实现这一目标,我首先搜索了我将如何阅读XML文件,这就是我所得到的:

[XML]$Web = Get-Content *path_to_XML_file*

使用点符号,我前往包含需要验证的行的节点(我仍然不知道如何找到行号以确定它是在它之前还是之后)。< / p>

我需要迭代的节点位于:

$Web.Configuration.location.'system.WebServer'.modules

当我输入最后一行时,继承人的控制台输出:

add
---
{HttpCacheModule, DynamicCompressionModule, IsapiFilterModule, ProtocolSupportModule...}

此节点包含名为&#39; add&#39;的其他节点的多个实例。但是类型为System.Array。

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

此外,还有一份XML中的模块节点的副本:

 <modules>
        <add name="HttpCacheModule" lockItem="true" />
            <add name="DynamicCompressionModule" lockItem="true" />   <--HERE
        <add name="IsapiFilterModule" lockItem="true" />
        <add name="ProtocolSupportModule" lockItem="true" />
        <add name="StaticFileModule" lockItem="true" />
        <add name="AnonymousAuthenticationModule" lockItem="true" />
        <add name="DefaultDocumentModule" lockItem="true" />
        <add name="CustomErrorModule" lockItem="true" />
        <add name="HttpRedirectionModule" lockItem="true" />
        <add name="RequestFilteringModule" lockItem="true" />
        <add name="IsapiModule" lockItem="true" />
        <add name="ConfigurationValidationModule" lockItem="true" />
            <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" />
            <add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" />
            <add name="WindowsAuthenticationModule" lockItem="true" />
            <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" />
            <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
            <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />
            <add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" />
            <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
            <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />
            <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />
            <add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" />
            <add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" />
            <add name="BasicAuthenticationModule" lockItem="true" />
            <add name="HttpLoggingModule" lockItem="true" />
            <add name="StaticCompressionModule" lockItem="true" />
            <add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler,runtimeVersionv2.0" />
            <add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
            <add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
            <add name="ClientLoggingHandler" />
            <add name="AdvancedLoggingModule" />
            <add name="AppWarmupModule" />
            <add name="RewriteModule" />  <---- HERE
            <add name="FailedRequestsTracingModule" lockItem="true" />
            <add name="F5XFFHttpModule" />
    </modules>

我需要确保行<add name="DynamicCompressionModule" lockItem="true" />绝对在<add name="RewriteModule" />之前执行,我不知道如何遍历此系统.Array到达那里。

有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:0)

您需要访问该对象。

($ Web.Configuration.location。&#39; system.WebServer&#39; .modules.add.name)将为您提供一个列表。

然后,您可以使用Foreach-Object或foreach循环。如果你想比较两个你可以使用的对象.IndexOf(&#39;&#39;)

($Web.Configuration.location.'system.WebServer'.modules.add.name).IndexOf('DynamicCompressionModule') #should return 1 since it is second in the list (and arrays start at zero)

($Web.Configuration.location.'system.WebServer'.modules.add.name).IndexOf('RewriteModule') #should return 34

这将遍历列表并允许您对每个名称执行某些操作

foreach ($a in $Web.Configuration.location.'system.WebServer'.modules.add.name) { $a }

删除&#39; name&#39;将显示&#39; lockItem&#39;资讯

foreach ($a in $Web.Configuration.location.'system.WebServer'.modules.add) {
    if ($a.lockItem -eq $true) { 
            $a 
    } 
}

这将列出lockItem设置为true的所有模块名称。

答案 1 :(得分:0)

You can navigate the add nodes using the NextSibling property. Since your array is not inherently indexed we just need to index the items you care about, and move the second one to the end if its in the wrong place. I just use $i to count up as we loop through nodes, and if we find either DynamicCompressionModule or RewriteModule I get the index of it, and I'll get the RewriteModule node so I can move it later if needed. Then if the index of DynamicCompressionModule is greater than that of RewriteModule I add a clone of RewriteModule after the last node of the array, and delete the original.

$i=0
$CurrentNode = $Web.Configuration.location.'system.WebServer'.modules.FirstChild

Do{
    $i
    $CurrentNode
    Switch($CurrentNode){
        {$_.Name -eq 'DynamicCompressionModule'}{$DCM=$i;$DCMNode=$CurrentNode}
        {$_.Name -eq 'RewriteModule'}{$RM=$i;$RMNode=$CurrentNode}
    }
    $i++
    $CurrentNode = $CurrentNode.NextSibling

}Until($CurrentNode -eq $Web.Configuration.location.'system.WebServer'.modules.LastChild)

If($DCM -gt $RM){
    "Moving RewriteModule to end of list"
    #Add a clone of the RewriteModule node after the last item in the 'add' array
    $Web.Configuration.location.'system.WebServer'.modules.AppendChild($RMNode.Clone())
    #Remove the original RewriteModule node since we now have a clone of it at the end of the array
    $Web.Configuration.location.'system.WebServer'.modules.RemoveChild($RMNode)
}Else{"No change needed"}