У меня есть два файла XML, которые я пытаюсь объединить. Я посмотрел на другие предыдущие вопросы, но я не чувствую, что могу решить свою проблему, читая их. Я считаю, что моя ситуация уникальна в том, что мне приходится находить элементы по значению атрибута, а затем сливаться в противоположный файл.Объединить два файла XML с помощью сопоставления элементов по значению атрибута
У меня есть два файла. Один из них - английский переводческий каталог, а второй - японский каталог переводов. Просьба см. Ниже.
В приведенном ниже коде вы увидите, что в XML есть три элемента, с которыми я буду объединять детей: MessageCatalogueEntry, MessageCatalogueFormEntry и MessageCatalogueFormItemEntry. У меня есть сотни файлов, и каждый файл имеет тысячи строк. Может быть больше элементов, чем те, которые я только что перечислил, но я точно знаю, что все элементы имеют «ключевой» атрибут.
Мой план:
- Итерация через File 1 и создать список всех значений «ключа» атрибута.
- В этом примере список будет
key_values = [321, 260, 320]
- В этом примере список будет
- Далее, я пойду через key_value список один за другим.
- Я буду искать файл 1 для элемента с атрибутом
key=321
. - Далее, возьмите ребенка элемента с
key=321
из файла 1. - Далее в файле 2, найти элемент с
key=321
и добавить дочерний элемент Я ранее захваченный из файла 1. - Далее я буду продолжить тот же цикл процесса через список
key_values
. - Далее я напишу новый корень xml в файл, чтобы сохранить кодировку utf8.
Файл 1:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE MessageCatalogue []>
<PackageEntry>
<MessageCatalogue designNotes="Undefined" isPrivate="false" lastKey="362" name="AddKMRichSearchEngineAdmin_AutoTranslationCatalogue" nested="false" version="3.12.0">
<MessageCatalogueEntry key="321">
<MessageCatalogueEntry_loc locale="" message="active"/>
</MessageCatalogueEntry>
<MessageCatalogueFormEntry key="260">
<MessageCatalogueFormEntry_loc locale="" shortTitle="Configuration" title="Spider Configuration"/>
</MessageCatalogueFormEntry>
<MessageCatalogueFormItemEntry key="320">
<MessageCatalogueFormItemEntry_loc hintText="" label="Manage Recognised Phrases" locale="" mnemonic="" scriptText=""/>
</MessageCatalogueFormItemEntry>
</MessageCatalogue>
</PackageEntry>
Файл 2:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE MessageCatalogue[]>
<PackageEntry>
<MessageCatalogue designNotes="Undefined" isPrivate="false" lastKey="362" name="" nested="false" version="3.12.0">
<MessageCatalogueEntry key="321">
<MessageCatalogueEntry_loc locale="ja" message="アクティブ" />
</MessageCatalogueEntry>
<MessageCatalogueFormEntry key="260">
<MessageCatalogueFormEntry_loc locale="ja" shortTitle="設定" title="Spider Configuration/スパイダー設定" />
</MessageCatalogueFormEntry>
<MessageCatalogueFormItemEntry key="320">
<MessageCatalogueFormItemEntry_loc hintText="" label="認識されたフレーズを管理" locale="ja" mnemonic="" scriptText="" />
</MessageCatalogueFormItemEntry>
</MessageCatalogue>
</PackageEntry>
Выход:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE MessageCatalogue []>
<PackageEntry>
<MessageCatalogue designNotes="Undefined" isPrivate="false" lastKey="362" name="AddKMRichSearchEngineAdmin_AutoTranslationCatalogue" nested="false" version="3.12.0">
<MessageCatalogueEntry key="321">
<MessageCatalogueEntry_loc locale="" message="active"/>
<MessageCatalogueEntry_loc locale="ja" message="アクティブ" />
</MessageCatalogueEntry>
<MessageCatalogueFormEntry key="260">
<MessageCatalogueFormEntry_loc locale="" shortTitle="Configuration" title="Spider Configuration"/>
<MessageCatalogueFormEntry_loc locale="ja" shortTitle="設定" title="Spider Configuration/スパイダー設定" />
</MessageCatalogueFormEntry>
<MessageCatalogueFormItemEntry key="320">
<MessageCatalogueFormItemEntry_loc hintText="" label="Manage Recognised Phrases" locale="" mnemonic="" scriptText=""/>
<MessageCatalogueFormItemEntry_loc hintText="" label="認識されたフレーズを管理" locale="ja" mnemonic="" scriptText="" />
</MessageCatalogueFormItemEntry>
</MessageCatalogue>
</PackageEntry>
У меня возникли проблемы просто даже захватывая элементы, фигу, захватывая их с помощью ключа стоимость. Например, я играл с библиотекой ElementTree, и я написал этот код в надежде получить только MessageCatalogueEntry, но я получаю только своих детей:
from xml.etree import ElementTree as et
tree_japanese = et.parse('C:\\blah\\blah\\blah\\AddKMRichSearchEngineAdmin_AutoTranslationCatalogue_JA.xml')
root_japanese = tree_japanese.getroot()
MC_japanese = root_japanese.findall("MessageCatalogue")
for x in MC_japanese:
messageCatalogueEntry = x.findall("MessageCatalogueEntry")
for m in messageCatalogueEntry:
print et.tostring(m[0], encoding='utf8')
tree_english = et.parse('C:\\blah\\blah\\blah\\AddKMRichSearchEngineAdmin\\AddKMRichSearchEngineAdmin_AutoTranslationCatalogue.xml')
root_english = tree_english.getroot()
MC_english = root_english.findall("MessageCatalogue")
for x in MC_english:
messageCatalogueEntry = x.findall("MessageCatalogueEntry")
for m in messageCatalogueEntry:
print et.tostring(m[0], encoding='utf8')
Любая помощь будет оценена. Я занимаюсь этим уже несколько рабочих дней, и я не ближе к финишу, чем когда был, когда начал!
Спасибо! Это работает так, как мне было нужно. Я действительно ценю твою помощь. Я бы поднял тебя, но у меня недостаточно репутации. Я обязательно вернусь и сделаю это, когда я получу квалификацию.
Одна вещь, которую мне интересно, это то, что мои заголовки (см. Ниже), если это правильный термин, не выписываются. Это не очень важно, я просто напишу строки в файл, так как заголовок одинаковый для всех файлов, с которыми я работаю. Xml version = "1.0" encoding = "utf-8"?> Еще раз спасибо! – alfonso
Да, lxml ожидает, что вы сами выведете заголовок. Я не помню всех подробностей. – tdelaney
Мне было интересно, знаете ли вы о другом способе разбора? Следующий ниже код удаляет теги CDATA, которые мне нужны: tree_english = lxml.etree.parse ('english.xml'). Я проверил документацию и, видимо, вы можете хранить теги CDATA, но похоже, что они используют один и тот же метод для анализа. Документация здесь: http://lxml.de/2.1/api.html – alfonso