2016-07-13 8 views
0

Ich habe diese XML-Dateistruktur, wobei der Name des übergeordneten Ordners die Auftragsnummer ist. Im Ordner befindet sich dann eine Datei mit demselben Namen wie der Ordner mit der Erweiterung .xml.Powershell XML-Skript zum Extrahieren von Wert aus <Eigenschaftsname = "xx" value = "yy" />

Powershell verwenden, für jeden Ordner und XML-Datei, muss ich den psModelled Wert des ersten Auftreten des <Property name="ProcessStatusID" value="psModelled"/> Tag abzurufen

Ich kann nicht herausfinden, wie der Wert der Eigenschaft zu erhalten. Hoffe, dass mir jemand mit diesem Code helfen kann.

Wenn der Wert = 'psClosed', dann muss ich den gesamten Ordner in einen anderen Archivordner verschieben, aber ich mache mir darüber Sorgen, sobald es mir gelingt, den Wert der Eigenschaft zu erhalten.

<?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> 

Hier ist mein Code so weit. Ich weiß, dass es Rookie-Code ist, aber ich bin ein PowerShell-Rookie.

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' 
      } 
      } 
     } 
    } 
} 

Und hier ist die aktuelle Ausgabe

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

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

Wenn ich Sie richtig verstehe, sollten Sie etwas wie folgt versuchen: '$ xml.SelectNodes ('// Eigenschaft') | ? {$ _. name -eq "ProcessStatusID"} | Wählen Sie "First 1 -ExpandProperty Wert" – n01d

+0

Super, danke n01d. Perfekt!! – Joe

Antwort

1

Ihr Powershell-Code ist ziemlich kompliziert, lassen Sie uns das zuerst aufräumen.

Sie haben ein Verzeichnis, das Unterverzeichnisse enthält, die *.xml Dateien enthalten. Sie sind daran interessiert, mit diesen Dateien zu arbeiten.

Get-ChildItem macht dies mit Wildcards einfach:

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

Jetzt können Sie die XML laden möchten und wählen Sie den „Wert des ersten Auftreten des <Property name="ProcessStatusID" value="psModelled"/> Tag“.

Der XPath-Ausdruck zum Auswählen dieser Elemente wäre //Property[@name = 'ProcessStatusID'].

Da wir nur das erste Vorkommen wollen, können wir the SelectSingleNode() method verwenden.

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" 
    } 
} 

Erledigt.

Werfen Sie einen Blick auf die FileInfo class, denn das ist die Art von Objekt Get-ChildItem gibt Ihnen hier.

+0

Tomalak, danke für den Code und die Erklärung. Es hat viel geholfen. Was ist der beste Weg, dies für die tägliche Ausführung zu planen? – Joe

+1

Wenn es half, anstatt "danke" in einem Kommentar zu sagen, upvote es. Upvotes sind das "nette" und "Dankeschön" dieser Seite. Ich bin sicher, dass Sie herausfinden können, wie Sie ein Skript unter Windows planen, das ist keine Raketenoperation. – Tomalak

0

Hier ist die Antwort auf n01d Hilfe basiert.

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 
      } 
      } 
    } 
} 
Verwandte Themen