XML-анализ Powershell не работает на подузлах - PullRequest
1 голос
/ 21 июля 2010

Я пытаюсь разобрать следующий файл:

<?xml version="1.0" encoding="UTF-8" ?> 
<printDrivers>
    <printDriver id="XE8550">
    <inf>x28550p.inf</inf>
    <driverPath>\drivers\XEROX\8550\8550_Driver</driverPath>
    <printerPaths>
            <printerPath>\\print-man\man-25</printerPath>
        </printerPaths>
    </printDriver>
    <printDriver id="HP4050TN">
        <inf>hpbf002i.inf</inf>
        <driverPath>\drivers\HP\LaserJet\LaserJet_4050_PCL6</driverPath>
        <printerPaths>
            <printerPath>\\print-man\man-8</printerPath>
            <printerPath>\\print-man\man-14</printerPath>
        </printerPaths>
    </printDriver>
  </printDrivers>

со следующим скриптом powershell:

$nodelist = $xd.selectnodes("/printDrivers/printDriver") # XPath is case sensitive
foreach ($printerDriverNode in $nodelist) {
    $XMLid = $printerDriverNode.getAttribute("id")
    $XMLinf = $printerDriverNode.selectSingleNode("inf").get_innerXml()
    $XMLdriverPath = $printerDriverNode.selectSingleNode("driverPath").get_innerXml()
    $printerPathNodeList = $printerDriverNode.selectNodes("printerPaths/printerPath")
        foreach ($printerPathNode in $printerPathNodeList) {
            $XMLprinterPath = $printerPathNode.selectSingleNode("printerPath").get_innerXml()
        }
}

Все работает нормально, кроме "вложенного" узла. Когда я запускаю скрипт, он получает только первый. то есть он не получит \ print-man \ man-14, только \ print-man \ man-8.

Как мне заставить его вернуть все узлы?

Спасибо

Ben

Ответы [ 5 ]

2 голосов
/ 21 июля 2010

Если у вас есть PowerShell V2.0, вы можете использовать Select-Xml, который генерирует объекты для вас на лету:

Select-Xml -Path "test.xml" -Xpath "/printDrivers/printDriver" | ForEach-Object {
    $id = $_.Node.id
    $inf = $_.Node.inf
    $driverPath = $_.Node.driverPath

    $_.Node | Select-Xml -Xpath "printerPaths/printerPath" | ForEach-Object {
        $printerPath = $_.Node.InnerText
    }
}
2 голосов
/ 21 июля 2010
 foreach ($printerPathNode in $printerPathNodeList) {
        $XMLprinterPath = $printerPathNode.selectSingleNode("printerPath").get_innerXml()
 }

Вы уже перебираете здесь узлы printerPaths/printerPath - нет необходимости делать еще один .selectsinglenode на этом узле <printerPath> - просто прочитайте .InnerXml или .InnerText с этого $printerPathNode -это должно дать вам значения, которые вы ищете

2 голосов
/ 21 июля 2010

Ожидается, что вы назначаете одну и ту же переменную ($ XMLprinterPath) несколько раз, поэтому второе значение переопределяет первое.Вы хотели использовать это как массив или список?

1 голос
/ 21 июля 2010

Я предполагаю, что вы пытаетесь сгладить XML в объекты

$r = $xml.printDrivers.printDriver | %{
        New-Object PSObject -Property @{
            id           = $_.id
            inf          = $_.inf
            driverPath   = $_.driverPath
            printerPaths = @(&{$_.printerPaths | % {$_.printerPath} })
        }
    }

$r[1].printerPaths
0 голосов
/ 21 июля 2010

У вас уже есть узел, поэтому просто используйте его:)

$nodelist = $xd.selectnodes("/printDrivers/printDriver") # XPath is case sensitive
foreach ($printerDriverNode in $nodelist) {
    $printerPathNodeList = $printerDriverNode.selectNodes("printerPaths/printerPath")
        foreach ($printerPathNode in $printerPathNodeList) {
            write-host $printerPathNode.get_innerXml()
        }
}

Обратите внимание, что возможно получить доступ к xml-подобным объектам.

$xd.printDrivers.printdriver | % { $_.id; $_.printerPaths.printerPath }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...