【问题标题】:Powershell xml script to extract value from <Property name="xx" value="yy"/>用于从 <Property name="xx" value="yy"/> 中提取值的 Powershell xml 脚本
【发布时间】:2016-07-13 23:15:01
【问题描述】:

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

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

我不知道如何获取属性值。希望有人可以帮助我编写该代码。

如果 value = '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

【问题讨论】:

  • 如果我理解正确,你应该尝试这样的事情:$xml.SelectNodes('//Property') | ?{$_.name -eq "ProcessStatusID"} | select -First 1 -ExpandProperty value
  • 太棒了,谢谢 n01d。完美!!

标签: xml powershell


【解决方案1】:

您的 Powershell 代码非常复杂,让我们先清理一下。

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

Get-ChildItem 使用通配符让这一切变得简单:

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

现在您要加载 XML 并选择 &lt;Property name="ProcessStatusID" value="psModelled"/&gt; 标记第一次出现的值”

选择这些元素的 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在这里给你的对象类型。

【讨论】:

  • Tomalak,感谢您的代码和解释。它帮助很大。现在,安排每天运行的最佳方式是什么?
  • 如果有帮助,不要在评论中说“谢谢”,而是点赞。 Upvotes 是本网站的“好”和“感谢”。我相信您可以弄清楚如何在 Windows 上安排脚本,这不是火箭手术。
【解决方案2】:

这是基于 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
             }
          }
    }
}

【讨论】:

    猜你喜欢
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    相关资源
    最近更新 更多