如何使用 PowerShell 重新格式化现有的 XML 文档

如何解决如何使用 PowerShell 重新格式化现有的 XML 文档

我正在尝试从此更新 XML 文档:

<Enclave id="OLD">
    <device>
        <name>MGMT</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
</Enclave>

<Enclave id="NEW">
    
    <device>
        <name>G-VDS-GooD</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC001</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC002</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
</Enclave>

为此:

<Enclave id="OLD">
    <device>
        <name>MGMT</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
</Enclave>

<Enclave id="NEW">
    
    <device>
        <name>G-VDS-GooD</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC001</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <cert>
             <inform>PEM</inform>
             <outform>PEM</outform>
             <name>G-VDS-ENC001</name>
             <type>WEBServer</type>
             <pwd>Password</pwd>
             <altSubject />
        </cert>
        <RequireCert>1</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC002</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <cert>
             <inform>PEM</inform>
             <outform>PEM</outform>
             <name>G-VDS-ENC002</name>
             <type>WEBServer</type>
             <pwd>Password</pwd>
             <altSubject />
        </cert>
        <RequireCert>1</RequireCert>
    </device>
</Enclave>

我已经编写了一些 PowerShell 命令(见下文),但只能做到这一点:

<Enclave id="OLD">
    <device>
        <name>MGMT</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
</Enclave>

<Enclave id="NEW">
    
    <device>
        <name>G-VDS-GooD</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <inform>PEM</inform>
        <outform>PEM</outform>
        <RequireCert>0</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC001</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <cert>
             <inform>PEM</inform>
             <outform>PEM</outform>
             <type>WEBServer</type>
             <pwd>Password</pwd>
             <altSubject />
        </cert>
        <RequireCert>0</RequireCert>
    </device>
    <device>
        <name>G-VDS-ENC002</name>
        <type>VoIP</type>
        <vlan>Voice2Network</vlan>
        <cert>
             <inform>PEM</inform>
             <outform>PEM</outform>
             <type>WEBServer</type>
             <pwd>Password</pwd>
             <altSubject />
        </cert>
        <RequireCert>1</RequireCert>
        <RequireCert>0</RequireCert>
    </device>
</Enclave>

这是我的 PowerShell 代码

$LoadType = "NEW"
$FileName = "C:\Voip.xml"
[xml]$FileOriginal = Get-Content $FileName
$Pattern = $FileOriginal.SelectNodes("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(),'G-VDS-ENC')]]")

foreach($Pat in $Pattern) {
    $inform = $FileOriginal.SelectSingleNode("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(),'G-VDS-ENC')]]/inform")
    $inform.ParentNode.RemoveChild($inform) | Out-Null

    $outform = $FileOriginal.SelectSingleNode("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(),'G-VDS-ENC')]]/outform")
    $outform.ParentNode.RemoveChild($outform) | Out-Null

    $RequireCert = $FileOriginal.SelectSingleNode("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(),'G-VDS-ENC')]]/RequireCert")
    $RequireCert.ParentNode.RemoveChild($RequireCert) | Out-Null

    # Create cert element 
    $cert = $FileOriginal.CreateElement('cert')

    $newinform = $FileOriginal.CreateElement('inform')
    $newinform.InnerText = 'PEM'

    $newoutform = $FileOriginal.CreateElement('outform')
    $newoutform.InnerText = 'PEM'

    $type = $FileOriginal.CreateElement('type')
    $type.InnerText = 'WebServer'

    $pwd = $FileOriginal.CreateElement('pwd')
    $pwd.InnerText = 'password'

    $altSubject = $FileOriginal.CreateElement('altSubject')

    $cert.AppendChild($newinform)
    $cert.AppendChild($newoutform)
    #$cert.AppendChild($name)
    $cert.AppendChild($type)
    $cert.AppendChild($pwd)
    $cert.AppendChild($altSubject)

    # Insert cert element after 'vlan' element
    $Pat.InsertAfter( $cert,$Pat.SelectSingleNode('vlan') ) 

    $newRequireCert = $FileOriginal.CreateElement('RequireCert')
    $newRequireCert.InnerText = "1"
    $Pat.InsertAfter( $newRequireCert,$Pat.SelectSingleNode('cert') )
}

$FileOriginal.Save($FileName)

我无法在 G-VDS-ENC001 和 G-VDS-ENC002 节点中以 1 属性正确显示“RequireCert”节点。此外,我无法想出任何关于如何将 G-VDS-ENC001 和 G-VDS-ENC002 节点元素克隆或复制到新创建的证书节点中的语法。谁能帮我弄清楚还需要什么或检查我糟糕的 PowerShell 代码

解决方法

您可以更新现有的 RequireCert 节点,而不是删除+重新创建它:

# Select the node
$RequireCert = $FileOriginal.SelectSingleNode("/Configuration/Enclave[@id = `"$LoadType`"]/device[name[contains(text(),'G-VDS-ENC')]]/RequireCert")
# Set the node's text value
$RequireCert.'#Text' = 1

然后您可以删除当前代码中的 $newRequireCert 部分。

,

我同意 Cpt.Whale 您不需要删除和重新创建 RequireCert 节点。

使用点表示法,您可以像这样更新这些节点:

(($FileOriginal.Configuration.Enclave | Where-Object { $_.id -eq $LoadType }).device | 
  Where-Object { $_.name -like 'G-VDS-ENC*' }) | ForEach-Object { $_.RequireCert = '1' }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?