Как я могу сравнить два объекта XML в Powershell - PullRequest
0 голосов
/ 09 октября 2019

У меня есть два объекта XML:

$objectWeb  = irm "http://server/webservice"   ## created by web service call
$objectFile = [XML](get-content ./myfile.xml)  ## returned from file

Я хочу сравнить их, чтобы определить, нужно ли мне продолжать работу в моем сценарии. Обычно все узлы совпадают, но мне нужно вывести любые узлы, которые этого не делают. Я бы обычно использовал compare-object, но он сравнивает только верхние узлы <xml> и <response>:

compare $objectWeb $objectFile  ## no output even on mismatched files

PS > $objectWeb
xml                            response
---                            --------
version="1.0" encoding="UTF-8" response

Обычно я мог бы сравнить свойства OuterXml обоих объектов, но get-content удаляет все пробелы/ linebreaks

Объекты выглядят так, со множеством подузлов ниже <message>:

PS > $objectFile.OuterXML

<?xml version="1.0" encoding="UTF-8"?><response><result>succeed</result><messages><message><type>info</type>...</message></messages></response>

PS > $objectWeb.OuterXML

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <result>succeed</result>
  <messages>
    <message>
      <type>info</type>
      ...
    </message>
  </messages>
</response>

Я дошел до того, что вместо этого читал их как текст, а затем разбивался на узлы кактак:

compare $objectWeb.outerxml.split("`n") (get-content ./myfile -raw).split("`n")

Так что теперь (с некоторым дополнительным усечением новых строк) compare-object фактически сравнивает каждый узел и показывает, какие из них отличаются, но я теряю все данные пути XML с этим методом, что приводит кпроблемы, если мне нужно знать родительские узлы.

Есть ли способ сравнить каждый узел как фактические объекты XML?

1 Ответ

0 голосов
/ 10 октября 2019

Я смог сделать это с помощью инструмента XMLDiff от Microsoft:

[Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null
Import-Module "C:\path\to\xmldiffpatch.dll"

$result  = New-Object System.Xml.Linq.XDocument
$diff    = New-Object microsoft.XmlDiffPatch.XmlDiff
$writer  = $result.CreateWriter()
$success = $diff.Compare($ObjectWeb, $ObjectFile, $writer)
$writer.Flush();$writer.Close()

Compare() возвращает логическое значение true / false, а $result представляет собой diffgram, который можно использовать для возврата каждого измененного узла и типов изменений (добавить | изменить | удалить).

Примечание 1: Этот инструмент имеет некоторые известные ошибки и работает немного медленнотак что будьте осторожны с большими файлами XML.

Примечание 2: Этот инструмент ведет себя по-разному внутри функции powershell, выдавая следующую ошибку:

# Exception calling "Compare" with "3" argument(s): "Could not find file 'C:\working\path\#document'."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...