2017-02-14 2 views
1

У меня есть файл XML с родительским узлом hospitalStore и несколько дочерних узлов мне нужно обрабатывать:Найти значение в XML и получить доступ к его братьев и сестер из одной и той же родительской группы

<?xml version="1.0" encoding="UTF-8"?><!--Hospital Store --> 
<hospitalStore><!-- Hospital Config --> 
    <src><!--Search Path For Files To Move--> 
     <path>C:\Users\Desktop\move\*.pdf</path> 
    </src> 
    <hospital> 
     <criteria>Beth Israel requirements</criteria> 
     <name>Beth Israel</name> 
     <category>OPBEIH</category> 
     <destination>C:\Users\Desktop\dest\1\</destination> 
     <hospcode>1101</hospcode> 
    </hospital><!-- End Hospital Config --><!-- Hospital Config --> 
    <hospital> 
     <criteria>Beth Israel CCC - WEST requirements</criteria> 
     <name>Beth Israel CCC WEST</name> 
     <category>OPBICC</category> 
     <destination>C:\Users\Desktop\dest\2\</destination> 
     <hospcode>1107</hospcode> 
    </hospital><!-- End Hospital Config --><!-- Hospital Config --> 
    <hospital> 
     <criteria>Beth Israel KHD requirements</criteria> 
     <name>Beth Israel KHD</name> 
     <category>OPBIKD</category> 
     <destination>C:\Users\Desktop\dest\3\</destination> 
     <hospcode>1102</hospcode> 
    </hospital><!-- End Hospital Config --><!-- Hospital Config --> 
    <hospital> 
     <criteria>Beth Israel KHD requirements</criteria> 
     <name>Beth Israel KHD</name> 
     <category>OPBIKE</category> 
     <destination>C:\Users\Desktop\dest\3\</destination> 
     <hospcode>1102</hospcode> 
    </hospital><!-- End Hospital Config --> 
</hospitalStore><!-- End Hospital Store --> 

Пока мой код извлекает файлы в директории, а затем соответствует первым 6 символам basename дочернему узлу XML category.

Я хочу, чтобы указать файл, соответствующий значению в XML category, на XML destination и т. Д., А затем проверить назначение с помощью нескольких других функций. Я не уверен, как связать файл с этой группой узлов.

$cPath="C:\move\outpatient.xml" 
$xml = New-Object -TypeName XML 
$xml.Load($cPath) 
$hName = $xml.hospitalstore.hospital 
$src = $xml.hospitalstore.src.path 
$fileList= get-childitem -path $src -File 

ForEach ($file in $fileList){ 

$category = ($file.BaseName.Substring(0,6)) 
$fileName = $fileList.Name 


if ($category -in $hName.category){ 


$file.Name 
$hName.category 

} 

} 

ответ

1

Чтобы найти hospital, который имеет дочерний узел, соответствующий category условию:

  • PowerShell 4+:

    $hospital = $hospitals.Where({ $_.category -eq $foo }, 'first')[0] 
    
  • PowerShell 3+:

    $hospital = $hospitals | Where category -eq $foo 
    

    Псевдонимы: Where = Where-Object = ?

  • PowerShell 1+:

    $hospital = $hospitals | Where { $_.category -eq $foo } 
    

    Псевдонимы: Where = Where-Object = ?

  • XPath (доступны во всех версиях PS для окон, но еще не в PowerShell для Linux AFAIK):

    $hospital = $xml.SelectSingleNode("//hospital[category='$foo']") 
    

Методы PowerShell 1,2,3 возвращают массив всех совпадающих узлов или одно совпадающее значение (а не массив) или ничего, итерируя весь массив. PowerShell 4 и SelectSingleNode останавливаются в первом матче.

Поэтому код шаблонного может быть что-то вроде этого:

$xml = New-Object XML 
$xml.Load('C:\move\outpatient.xml') 

$hospitals = $xml.hospitalStore.hospital 

Get-ChildItem $src -File | ForEach { 
    $file = $_ 
    $fileCategory = $file.BaseName.Substring(0,6) 
    $fileName = $file.Name 

    $hospital = $hospitals | Where { $_.category -eq $fileCategory } 
    if (!$hospital) { 
     Write-Error "$fileCategory not found in XML" 
     return # return because we're inside a function-like ScriptBlock 
    } 
    # use the values 
    echo $hospital.criteria 
    echo $hospital.name 
    echo $hospital.destination 
    echo $hospital.hospcode 
    echo '' 
}