Powershell xml脚本从<property name =“xx”value =“yy”>中提取值

时间:2016-07-13 14:18:12

标签: xml powershell

我有这个xml文件结构,其中父文件夹名称是作业号。然后在文件夹中,有一个文件与扩展名为.xml的文件夹同名。

使用PowerShell,对于每个文件夹和xml文件,我需要检索第一次出现psModelled标记的<Property name="ProcessStatusID" value="psModelled"/>

我无法弄清楚如何获取属性值。希望有人能帮我解决这个问题。

如果值='psClosed',那么我需要将整个文件夹移动到另一个存档文件夹,但是一旦我成功获取属性值,我就会担心。

<?xml version="1.0"?>
<DentalContainer version="2016-1">
  <Object name="MainObject" type="TDM_Container">
    <Object name="OrderList" type="TDM_List_Order">
      <List name="Items">
        <Object type="TDM_Item_Order">
          <Property name="IntOrderID" value="6862911"/>
          <Property name="TraySystemType" value="stNone"/>
        </Object>
      </List>
    </Object>
    <Object name="ModelJobList" type="TDM_List_ModelJob">
      <List name="Items">
        <Object type="TDM_Item_ModelJob">
          <Property name="ModelJobID" value="MJA98D88967006476CB010B2C41328F5A4"/>
          <Property name="OrderID" value="6862911"/>
        </Object>
      </List>
    </Object>
    <Object name="ModelElementList" type="TDM_List_ModelElement">
      <List name="Items">
        <Object type="TDM_Item_ModelElement">
          <Property name="ModelElementID" value="MEA4A179CFB6B74BC2A38373D720629ECE"/>
          <Property name="ProcessStatusID" value="psModelled"/>
          <Property name="ValidationResult" value="vrPassed"/>
        </Object>
      </List>
    </Object>
    <Object name="ElementList" type="TDM_List_Element">
      <List name="Items">
        <Object type="TDM_Item_Element">
          <Property name="ElementID" value="TEC89CECF82CAD4F54B3E26A56E40971FA"/>
          <Property name="CacheTypeClass" value="teAbutment"/>
        </Object>
      </List>
    </Object>
  </Object>
</DentalContainer>

到目前为止,这是我的代码。我知道这是新手代码,但我是PowerShell的新手。

Get-ChildItem C:\temp\pwrshell2 | ForEach-Object -Process {
    if ($_.PSIsContainer)
    {
        # // Store subfolder path in a variable
        $sFolderPath = $_.FullName
        $sFolderName = Split-Path $sFolderPath -Leaf

        if ($sFolderName -eq '6862911')
        {

          Get-ChildItem $sFolderPath | Where {$_.Name -like $sFolderName + '.xml'} | foreach{

            $sFilepath = $_.FullName

            'FilePath='+$sFilepath
            'length='+$sFilepath.Length

             [xml]$xml = Get-Content $sFilepath
             $sNode = $xml.selectNodes('//Property') | select Name

             $sNode+'-->sNode length='+$sNode.Length

             if ($sNode -eq 'ProcessStatusID')
             {
               'inside the loop'
             }
          }
        }
    }
}

这是当前的输出

FilePath=C:\temp\pwrshell2\6862911\6862911.xml
length=37

name                                                                                                                                                                                                                                                               
----                                                                                                                                                                                                                                                               
IntOrderID                                                                                                                                                                                                                                                         
TraySystemType                                                                                                                                                                                                                                                     
ModelJobID                                                                                                                                                                                                                                                         
OrderID                                                                                                                                                                                                                                                            
ModelElementID                                                                                                                                                                                                                                                     
ProcessStatusID                                                                                                                                                                                                                                                    
ValidationResult                                                                                                                                                                                                                                                   
ElementID                                                                                                                                                                                                                                                          
CacheTypeClass                                                                                                                                                                                                                                                     
-->sNode length=
9

2 个答案:

答案 0 :(得分:1)

你的Powershell代码非常令人费解,让我们首先清理它。

您有一个目录,其中包含子目录,其中包含*.xml个文件。您有兴趣使用这些文件。

Get-ChildItem通过通配符轻松实现这一点:

Get-ChildItem C:\temp\pwrshell2\*\*.xml

现在您要加载XML并选择第一次出现<Property name="ProcessStatusID" value="psModelled"/>代码的“值。

选择这些元素的XPath表达式为//Property[@name = 'ProcessStatusID']

由于我们只想要第一次出现,我们可以使用the SelectSingleNode() method

Get-ChildItem C:\temp\pwrshell2\*\*.xml | foreach {
    echo $_.FullName 

    [xml]$doc = Get-Content $_
    $ProcessStatusID = $doc.SelectSingleNode("//Property[@name = 'ProcessStatusID']")

    # never forget to check if there even is a match
    if ($ProcessStatusID) {
        echo "ProcessStatusID: $($ProcessStatusID.value)"

        if ($ProcessStatusID.value -eq "psClosed") {
            $_.Directory | Move-Item -Destination C:\ArchiveFolder
        }
    } else {
        echo "ProcessStatusID not found"
    }
}

完成。

查看FileInfo class,因为这是Get-ChildItem对象的类型。

答案 1 :(得分:0)

以下是基于n01d帮助的答案。

Get-ChildItem C:\temp\pwrshell | ForEach-Object -Process {
    if ($_.PSIsContainer)
    {
        # // Store subfolder path in a variable
        $sFolderPath = $_.FullName
        $sFolderName = Split-Path $sFolderPath -Leaf

          Get-ChildItem $sFolderPath | Where {$_.Name -like $sFolderName + '.xml'} | foreach{

            $sFilepath = $_.FullName

            'FilePath='+$sFilepath

             [xml]$xml2 = Get-Content $sFilepath
             $sValue = $xml2.SelectNodes('//Property') | ?{$_.name -eq "ProcessStatusID"} | select -First 1 -ExpandProperty value
             '$sValue='+$sValue

             if ($sValue -eq 'psClosed')
             {
               Move-Item $sFolderPath C:\temp\pwrshell3
             }
          }
    }
}