2015-12-16 2 views
1

Я работаю с XML-документом, и я не уверен, как его разобрать, чтобы найти определенный узел.Идентификация конкретного узла в XML с помощью PowerShell

В приведенном ниже примере я бы искал ProductB и ожидая, чтобы идентифицировать пчелиный улей

<PRODUCTS> 
    <PRODUCT_LEVEL_1> 
     <PRODUCT_ID>ProductA</PRODUCT_ID> 
     <PRODUCT_NAME>Ant Hill</PRODUCT_NAME> 
     <PRODUCT_ID>ProductB</PRODUCT_ID> 
     <PRODUCT_NAME>Bee Hive</PRODUCT_NAME> 
     <PRODUCT_ID>ProductC</PRODUCT_ID> 
     <PRODUCT_NAME>Centipede Hotel</PRODUCT_NAME> 
    </PRODUCT_LEVEL_1> 
</PRODUCTS> 

Я даже не знаю, как относиться к этому формату XML, который делает его трудно искать.

Любая помощь с благодарностью получена.

Edit: В настоящее время я загрузки XML из файла, используя следующие:

System.Xml.XmlDocument] $xd = new-object System.Xml.XmlDocument 
$file = resolve-path($inputFile) 
$xd.load($file) 
$nodelist = $xd.selectnodes("/PRODUCTS/PRODUCT_LEVEL_1") 
foreach ($documentNode in $nodelist) { 
    #do some stuff 
} 

Фактический файл XML имеет множество других мусор в тоже, но я раздели его в надежде сосредоточив внимание на бит мне нужен. Возможно, я слишком много разделил, и контекст был потерян?

+0

EDIT: Почему раздел комментариев не поддерживает мои разрывы? Спасибо за быстрый ответ PetSerAl. Мне интересно, как это использовать в моем существующем коде. На данный момент я загрузил документ XML и выбрал все узлы в $ nodelist. Затем я использую foreach для прохождения через каждый узел . – user3107615

+0

Я не могу понять, как опубликовать код - каждый раз, когда я нажимаю, он принимает это как комментарий !! – user3107615

+0

Спасибо за это! :) – user3107615

ответ

1

Вы можете использовать XPath для выполнения этой задачи. У XPath есть оси, которые позволяют ссылаться на предшествующие и следующие элементы документа:

filter Prepare-StringForXPath { 
    param(
     [Parameter(ValueFromPipeline)] 
     [String]$String 
    ) 
    if($String -notlike '*''*') { 
     "'$String'" 
    } elseif($String -notlike '*"*') { 
     """$String""" 
    } else { 
     “concat($(($String -split '(?<=''[^"]*)(?=")|(?<="[^'']*)(?='')' | Prepare-StringForXPath) -join ', '))” 
    } 
} 

$xd = [Xml]@' 
<PRODUCTS> 
    <PRODUCT_LEVEL_1> 
     <PRODUCT_ID>ProductA</PRODUCT_ID> 
     <PRODUCT_NAME>Ant Hill</PRODUCT_NAME> 
     <PRODUCT_ID>ProductB</PRODUCT_ID> 
     <PRODUCT_NAME>Bee Hive</PRODUCT_NAME> 
     <PRODUCT_ID>ProductC</PRODUCT_ID> 
     <PRODUCT_NAME>Centipede Hotel</PRODUCT_NAME> 
    </PRODUCT_LEVEL_1> 
</PRODUCTS> 
'@ 

$ProdName = Read-Host 'Input product name' 
$ProdID = $xd.SelectSingleNode("//PRODUCT_NAME[.=$(Prepare-StringForXPath $ProdName)]/preceding-sibling::PRODUCT_ID[1]").InnerText 
"Product ID for '$ProdName' is '$ProdID'." 

$ProdID = Read-Host 'Input product ID' 
$ProdName = $xd.SelectSingleNode("//PRODUCT_ID[.=$(Prepare-StringForXPath $ProdID)]/following-sibling::PRODUCT_NAME[1]").InnerText 
"Product name for '$ProdID' is '$ProdName'." 
Смежные вопросы