Powershell XML解析不在子节点上工作

时间:2010-07-21 12:34:44

标签: xml powershell xpath

我要解析以下文件:

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

如何让它恢复所有节点?

谢谢,

5 个答案:

答案 0 :(得分:2)

这是预期的,你要多次分配相同的变量($ XMLprinterPath),所以第二个值会覆盖第一个。您是否打算将其用作数组或列表?

答案 1 :(得分:2)

 foreach ($printerPathNode in $printerPathNodeList) {
        $XMLprinterPath = $printerPathNode.selectSingleNode("printerPath").get_innerXml()
 }

您已在此处迭代printerPaths/printerPath个节点 - 无需在该.selectsinglenode节点上执行另一个<printerPath> - 只需阅读.InnerXml或{{1}来自那个.InnerText - 应该为你提供你正在寻找的价值

答案 2 :(得分:2)

如果您有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
    }
}

答案 3 :(得分:1)

我猜您正在尝试将XML展平为对象

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

$r[1].printerPaths

答案 4 :(得分:0)

您已拥有该节点,因此只需使用它:)

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