Для каждой строки списка получите строку, найдите конкретный узел в XML и удалите родительский узел с помощью Powershell. - PullRequest
0 голосов
/ 24 июня 2018

У меня есть список со строками, для каждой строки которого есть соответствующий узел в файле XML.Все родители должны быть удалены в этом XML.Скрипт работает примерно, но результат неверный.И я получаю некоторые ошибки с переменной $line внутри запроса Xpath.Я пытаюсь выяснить, что происходит с этой переменной.

romlist.txt:

1941.zip
llander.zip
warrior.zip

gamelist.xml:

<?xml version="1.0" encoding="UTF-8"?>
  <gameList>
      <game id="46415" source="screenscraper.fr">
          <path>.aaa/bbb/warrior.zip</path>
          <name>Warrior</name>
          <desc>qweqwe</desc>
          <image>./images/warrior-image.png</image>
          <rating>0.7</rating>
          <releasedate>19790101T000000</releasedate>
          <developer>Tim Skelly</developer>
          <publisher>Vectorbeam</publisher>
          <genre>Fight / N/A</genre>
          <players>2</players>
          <video>./videos/warrior-video.mp4</video>
      </game>
      <game id="39873" source="screenscraper.fr">
          <path>.ccc/ddd/1941.zip</path>
          <name>1941 - Counter Attack</name>
          <desc>asdasd</desc>
          <image>./images/1941-image.png</image>
          <rating>0.8</rating>
          <releasedate>19900101T000000</releasedate>
          <developer>Capcom</developer>
          <publisher>Capcom</publisher>
          <genre>Shoot'em up / Vertical / Shoot'em Up</genre>
          <players>2</players>
          <video>./videos/1941-video.mp4</video>
      </game>
      <game id="46408" source="screenscraper.fr">
          <path>.eee/fff/sundance.zip</path>
          <name>Sundance</name>
          <desc>zxczxc</desc>
          <image>./images/sundance-image.png</image>
          <rating>0.5</rating>
          <releasedate>19790101T000000</releasedate>
          <developer>Tim Skelly</developer>
          <publisher>Cinematronics</publisher>
          <genre>N/A / Various</genre>
          <players>2</players>
          <video>./videos/sundance-video.mp4</video>
      </game>
      <game id="46393" source="screenscraper.fr">
          <path>.ggg/hhh/llander.zip</path>
          <name>Lunar Lander</name>
          <desc>asdasd</desc>
          <image>./images/llander-image.png</image>
          <rating>0.9</rating>
          <releasedate>19790101T000000</releasedate>
          <developer>Atari</developer>
          <publisher>Atari</publisher>
          <genre>Various / N/A / Simulation</genre>
          <players>1</players>
          <video>./videos/llander-video.mp4</video>
      </game>
  </gameList>

POWERSHELL:

$input = "gamelist.xml"
$output = "gamelist_result.xml"
$romlist = "romlist.txt"

[xml]$xml = Get-Content -Path $input -Raw

ForEach($line in Get-Content $romlist) {
    $rom = $xml.selectSingleNode('//game/path[contains(text(),line)]') | Select-Object -ExpandProperty "#text"
    ForEach($node in $xml.gameList.game | Where-Object {$_.path -eq $rom})
    {
    $xml.gameList.RemoveChild($node)
    }
}

$path = (join-path $pwd $output)
$xml.Save($path)

Если $xml.selectSingleNode('//game/path[contains(text(),line)]'), у нас нет ошибок, но результат неправильный.

Если $xml.selectSingleNode('//game/path[contains(text(),$line)]') мыесть некоторые ошибки, и результат инвертируется, где список сохраняется вместо того, чтобы быть удаленным.

Буду признателен за любую помощь в решении этой проблемы

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Ваш код почти правильный, но в этой строке есть проблема:

$xml.selectSingleNode('//game/path[contains(text(),line)]')

Если вы хотите, чтобы Powershell заменил значение line, используйте внешние двойные кавычки и $. Также необходимо добавить буквальные одинарные кавычки вокруг $line, потому что функция contains ожидает их для разграничения значения.

$xml.selectSingleNode("//game/path[contains(text(),'$line')]")

С этим изменением оно должно работать. Однако я немного изменил рефакторинг, чтобы сделать его более лаконичным.

ForEach($line in Get-Content $romlist) {
    $rom = $xml.selectSingleNode("//game/path[contains(text(),'$line')]") | Select-Object -ExpandProperty "#text"
    $xml.gameList.ChildNodes | Where-Object{ $_.path -eq $rom } | ForEach-Object { $xml.gameList.RemoveChild($_) } 
}
0 голосов
/ 24 июня 2018

Если я вас правильно понял.

$rom, $inp = 'C:\path\romlist.txt', 'C:\path\gamelist.xml'
($lst, $xml = (Get-Content $rom), [xml](Get-Content $inp))[0].ForEach{
   $nod = $xml.SelectSingleNode("//path[contains(text(), '$_')]")
   [void]$xml.gameList.RemoveChild($nod.ParentNode)
}
$xml.Save('C:\path\gamelist_result.xml')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...