确定XML节点存在

mac*_*ack 15 xml powershell powershell-2.0

这可能很简单,但我正在尝试确定XML文档中是否存在节点.我以为我在这篇文章中找到了答案, 如何使用PowerShell检查节点是否存在而不会出现异常?,但我没有得到它的工作.这是我最近的尝试.

foreach ($vendor in $xml.Vendors.Vendor| Where-Object  {$_.Type -match "Send"}) {
    $NodeExists = $vendor.SelectSingleNode($vendor.EncKey)
    if ($NodeExists -ne $null) {
        # Do something
    }
    else {
       # something else
    }
   }
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

编辑:这是我的测试文件中的XML.我需要找出每个供应商存在的EncKey或注释.

<?xml version="1.0" encoding="UTF-8"?>
    <!-- Vendors we will send and retreive files from Get-Send means we will get a file and send them a file Send means we will only send them a file-->
    <Vendors>
        <Vendor Type="Get-Send">
            <Name>Vendor1</Name>            
            <RemotePath>/Remote/Path1/</RemotePath>
            <EncKey>pgpenc.key</EncKey>
        </Vendor>
        <Vendor Type="Send">
            <Name>Vendor2</Name>            
            <RemotePath>/Remote/Path2/</RemotePath> 
            <!-- This one has no EncKey -->         
        </Vendor>
    </Vendors>
Run Code Online (Sandbox Code Playgroud)

Ale*_*zie 8

我能想到的最简单的方法是尝试将节点值写入变量,然后查看该变量是否为null.这是标准书店xml文件的示例.

[xml]$bookstore = Get-Content .\bookstore.xml
foreach ($book in $bookstore.bookstore.book | Where-Object {$_.Type -match "novel"}) {
 $NodeExists = $book.author
 if($NodeExists){
  Write-Host $book.author
 }
 else{
  Write-Host 'No Author'
 }
} 
Run Code Online (Sandbox Code Playgroud)

所以对于你的脚本,我认为它可能是

$NodeExists = $null
foreach ($vendor in $xml.Vendors.Vendor| Where-Object  {$_.Type -match "Send"}) {
 $NodeExists = $vendor.EncKey
 if ($NodeExists) {
  # Do something
 }
 else {
  # something else
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢Alex.这与我试图做的一致,但如果$ vendor.EncKey不存在,我会得到一个异常:**在此对象上找不到属性'EncKey'.确保它存在.**我永远不会到声明的"其他"部分. (2认同)
  • @mack 当您打开 [严格模式](https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/Set-StrictMode?view=powershell) 时,您实际上会遇到异常-5.0)。当严格模式关闭时,`$vendor.EncKey` 在语句 `if ( $vendor.EncKey )` 中的计算结果为 `$false`,由@Jay 提供 (2认同)

mac*_*ack 8

看来我对 SelectSingleNode 使用了错误的语法。这是一个工作示例。

[xml]$xml = @'
<?xml version="1.0" encoding="UTF-8"?>
    <!-- Vendors we will send and retreive files from Get-Send means we will get a file and send them a file Send means we will only send them a file-->
    <Vendors>
        <Vendor Type="Get-Send">
            <Name>Vendor1</Name>            
            <RemotePath>/Remote/Path1/</RemotePath>
            <EncKey>pgpenc.key</EncKey>
        </Vendor>
        <Vendor Type="Send">
            <Name>Vendor2</Name>            
            <RemotePath>/Remote/Path2/</RemotePath> 
            <!-- This one has no EncKey -->         
        </Vendor>
    </Vendors>
'@

foreach ($vendor in $xml.Vendors.Vendor| Where-Object  {$_.Type -match "Send"}) {
    $NodeExists = $vendor.SelectSingleNode("./EncKey")
    if ($NodeExists -ne $null) {
        write-host "EncKey is null"
    }
    else {
       write-host "EncKey is not null"
    }
   }

EncKey is null
EncKey is not null
Run Code Online (Sandbox Code Playgroud)

感谢大家的帮助。

  • 很好,但应该相反。if ($NodeExists -ne $null) { write-host "EncKey 不为空" } (2认同)

Ale*_*ild 5

假设您使用以下命令将 $xml 对象加载为 XmlDocument

$xml = new-object System.Xml.XmlDocument
$xml.LoadXml( (get-content $pathToXmlFile) )
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做,这更简单:

if ($vendor.encKey -ne $null) {
  # does exist
} else {
  # does not exist
}
Run Code Online (Sandbox Code Playgroud)

  • 否决,因为如果该元素不存在,则会引发异常。 (3认同)