У меня есть две большие (> 100 МБ, несколько миллионов строк каждая) XML-файлы, которые структурированы следующим образом.Powershell - сравнить части двух больших файлов XML
<?xml version='1.0' encoding='UTF-8'?>
<index>
<doc id='0'>
<field name='PART' norm='-1' flags='Idfp--S--Ni08--------'>
<val>12345-678</val>
</field>
<field name='DESCRIPTION' norm='-1' flags='Idfp--S--Ni08--------'>
<val>Part XYX123 Description</val>
</field>
<field name='QTY' norm='-1' flags='Idfp--S--Ni08--------'>
<val>18</val>
</field>
<field name='VENDOR' norm='-1' flags='Idfp--S--Ni08--------'>
<val>ACME</val>
</field>
<field name='MFG' norm='-1' flags='Idfp--S--Ni08--------'>
<val></val>
</field>
</doc>
<doc id='1'>
<field name='PART' norm='124' flags='Idfp--S--Ni08--------'>
<val>ABCD-1234</val>
</field>
<field name='DESCRIPTION' norm='-1' flags='Idfp--S--Ni08--------'>
<val>PART ABCD Description</val>
</field>
<field name='QTY' norm='-1' flags='Idfp--S--Ni08--------'>
<val>4</val>
</field>
<field name='VENDOR' norm='-1' flags='Idfp--S--Ni08--------'>
<val></val>
</field>
<field name='MFG' norm='-1' flags='Idfp--S--Ni08--------'>
<val></val>
</field>
</doc>
</index>
Мне нужно найти предметы, которые находятся в одном, но не другом, и наоборот. Первоначально я хочу сравнить значение атрибута PART
, но хотел бы также сравнить другие значения (описание и т. Д.).
Я хочу, чтобы определить, что в xmlfile1:
index/doc/field name=part/val - 12345-678
также в xmlfile2. Если нет, напишите его в файл text/csv.
Я пробовал использовать Compare-Object
& Get-Content
, но одной из проблем, с которыми я столкнулся, являются другие атрибуты, которые содержатся в каждом файле XML. Оба XML файлов могут иметь
index/doc/field name=part/val - 12345-678
, но разница в том, что xmlfile1 может иметь разные значения для нормы & флагов атрибутов, чем xmlfile2. Который делает с использованием Compare-Object
& Get-Content
флаг все.
Использование Powershell, как бы вы сделали сравнение, игнорируете атрибуты «шум», но отвечаете на <value>
только для атрибута PART
?
EDIT
Для уточнения - второй файл XML будет почти идентичен показанному. Однако, что может быть иначе: <doc id='0'>
в любом из XML, <field name='PART'
будет таким же, но другие атрибуты norm='-1'
и flags='Idfp--S--Ni08--------'>
могут быть разными. Я хотел бы найти атрибут PART, игнорировать остальные атрибуты в field
и определить, существует ли содержимое в <val>
во втором XML-файле.
У вас есть образец xmlfile2? Как бы вы узнали, какие элементы сравнивать? Поскольку вы говорите, что значение PART МОЖЕТ быть одинаковым, тогда это бесполезно. Что статично? Статический doc-id? –
@ FrodeF.- Я добавил дополнительную информацию для ясности. Атрибут 'name' будет статичным, а остальные (' norm', 'flags') могут иметь разные значения. Если атрибут 'name = PART', я хочу определить, находится ли что-то в' 'в XML-файле 2. Игнорируйте остальные атрибуты в этой строке. Кроме того, значение в '
Как я уже сказал, там вполне может быть более эффективным ответ, но это должно быть эффективным, тем не менее.
источник
2016-03-02 19:24:45 TheMadTechnician
Мне нужен более эффективный ответ. С двумя большими XML-файлами 'Get-Content' выдает ошибку« Out of Memory », прежде чем я смогу загрузить первый файл XML. Прекрасно работает для небольших файлов. –
Я бы использовал тот же тип решения, что и ответ @ TheMadTechnician, но для этого требуется немного памяти (по крайней мере, когда у вас большие файлы). Однако есть способы его оптимизации. Вы говорите, что у него заканчивается память
Get-Content
.Get-Content
создает объект-массив со строкой в строке. Поскольку мы все равно будем передавать его в xml-документ, мы можем прочитать файл как простую строку, которая должна сэкономить нам много памяти.Если у вас все еще есть проблемы, вы можете запустить этот скрипт на компьютере с большим количеством ресурсов. XML-синтаксический анализ проще, если мы сможем сначала сохранить весь файл в памяти.
Вы также можете использовать хеш-решения, где вы храните значения из file1 и сравнить значения с тем, когда вы читаете file2. Пример:
Выход:
Это просто концепция доказательства правильности использования регулярных выражений. С помощью такого синтаксического анализа текста (используя exhtables для хранения значений) вы можете использовать
StreamReader
для чтения одной строки за раз, чтобы минимизировать использование памяти.источник
2016-03-03 16:39:18