简体   繁体   English

PowerShell:定位节点并读取其客户端节点

[英]PowerShell: Locate node and read its client nodes

In the XML file documented below I need to do the following:在下面记录的 XML 文件中,我需要执行以下操作:

  • Check in the structures 'General', 'Exceptions.Weekday name="Aaa"' or 'Exceptions.Date name="dd.MM.yyyy"' whether the node 'Mode name="Day"' resp.检查结构 'General'、'Exceptions.Weekday name="Aaa"' 或 'Exceptions.Date name="dd.MM.yyyy"' 节点 'Mode name="Day"' 是否对应。 'Mode name="Evening"' exists (without producing error output in case the node does not exist) 'Mode name="Evening"' 存在(如果节点不存在,则不会产生错误输出)
  • If the node exists read of each client node its content如果节点存在,则读取每个客户端节点的内容

The XML file has the following content: XML 文件具有以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<P3Dcontrol>
  <General>
    <Mode name="Day">
      <P3DVersion>v4</P3DVersion>
      <FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
      <TacPackState>Inactive</TacPackState>
    </Mode>
    <Mode name="Evening">
      <P3DVersion>v4</P3DVersion>
      <FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
      <TacPackState>Active</TacPackState>
    </Mode>
  </General>
  <Exceptions>
    <Weekday name="Monday">
      <Mode name="Evening">
        <P3DVersion>v4</P3DVersion>
        <FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
        <TacPackState>Inactive</TacPackState>
      </Mode>
    </Weekday>
    <Date name="27.10.2020">
      <Mode name="Day">
        <P3DVersion>v5</P3DVersion>
        <FlightFile>Maule-LSZH-Schoen.fxml</FlightFile>
        <TacPackState>Inactive</TacPackState>
      </Mode>
    </Date>
  </Exceptions>
</P3Dcontrol>

I setup the code to read the client nodes of a node I know exists but I have not been successful;我设置了代码以读取我知道存在但未成功的节点的客户端节点; the results in the array $controlData are all empty:数组 $controlData 中的结果都是空的:

# Set up working data
$mode        = GetCurrentMode # get current mode ('Day' or 'Evening')
$controlData = @{}    # initialise array for data read

# Set up new XML object and read control file content
$xmlControl = New-Object System.XML.XMLDocument
$xmlControl.Load($controlFileSpec)

# Get <General>.<Mode name=$mode> node content
$xmlControl.P3Dcontrol.General.SelectSingleNode("Mode[@Name = $mode]") | ForEach-Object {
  $controlData["P3DVersion"]   = $_.P3DVersion
  $controlData["FlightFile"]   = $_.FlightFile
  $controlData["TacPackState"] = $_.TacPackState
}

Thanks a lot for your help or hints Hannes非常感谢您的帮助或提示 Hannes

Once you have the XML document in $xmlControl, you should be able to work with it using standard PowerShell constructs.在 $xmlControl 中拥有 XML 文档后,您应该能够使用标准的 PowerShell 构造来使用它。 Perhaps something like this:也许是这样的:

$controlData = $xmlControl.P3Dcontrol.General.Mode | Where-Object { $_.Name -eq $mode } | Select-Object P3DVersion,FlightFile,TacPackState

You can also save a line or two by using [xml] to parse XML data.您还可以通过使用[xml]解析 XML 数据来保存一两行。


edit:编辑:

The above line will get you a custom Powershell object, where you can access the properties as $controlData.P3DVersion , $controlData.FlightFile , etc. If you need to have an array, you can keep the ForEach-Object part from your original code.上面的行将为您提供一个自定义的 Powershell 对象,您可以在其中访问$controlData.P3DVersion$controlData.FlightFile等属性。如果您需要一个数组,您可以保留原始代码中的ForEach-Object部分. Something like this:像这样的东西:

$xmlControl.P3Dcontrol.General.Mode | Where-Object { $_.Name -eq $mode } | ForEach-Object {
     $controlData["P3DVersion"]   = $_.P3DVersion
     $controlData["FlightFile"]   = $_.FlightFile
     $controlData["TacPackState"] = $_.TacPackState
}

You can do the following to update your hash table:您可以执行以下操作来更新哈希表:

$mode = 'Day'
$controlData = @{} 
$controlFileSpec = 'c:\temp\x.xml'
$xmlControl = New-Object System.XML.XMLDocument
$xmlControl.Load($controlFileSpec)

$xmlControl.P3Dcontrol.General.SelectSingleNode("Mode[@name = '$mode']") | ForEach-Object {
  $controlData["P3DVersion"]   = $_.P3DVersion
  $controlData["FlightFile"]   = $_.FlightFile
  $controlData["TacPackState"] = $_.TacPackState
}

String values in XPATH expressions need to be quoted. XPATH 表达式中的字符串值需要被引用。 Since your XPATH expression contains outer double quotes, then variables will be substituted inside.由于您的 XPATH 表达式包含外部双引号,因此将在内部替换变量。 You can then just use single quotes around your variables that represent values.然后,您可以在表示值的变量周围使用单引号。

XPATH expressions are case-sensitive. XPATH 表达式区分大小写。 So @Name and @name are different.所以@Name@name是不同的。 Since your XML contains lowercase name attributes, you will need to match that in your expression.由于您的 XML 包含小写name属性,因此您需要在表达式中匹配该属性。

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

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