2013-11-12 5 views
0

У меня есть два XML-кода, которые выглядят ниже. Как объединить 2 из них с помощью сценариев, чтобы принимать значение от new.xml & retainging несуществующего значения атрибута формы base.xmlСлияние двух XML с сохраняющим значением атрибута из base-xml

base.xml:

<element name="ind" 
      dbs="name1, name2, name4" 
      server="ServerName" 
      good-attribute="234"/> 

Моего new.xml выглядит следующим образом:

<element name="ind" 
     description="My desc" 
     dbId="someId" 
     moreAttr="someVal" 
     dbs="name1, name2, name4, name12, name3" 
     server="ServerName" /> 

Я хотел бы принять последнюю dbs значение от new.xml до merge.xml и с сохранением good-attribute значения присутствует только в base.xml:

merge.xml:

<element name="ind" 
     description="My desc" 
     dbId="someId" 
     moreAttr="someVal" 
     dbs="name1, name2, name4, name12, name3" 
     server="ServerName" 
     good-attribute="234" /> 

С пастой только paste fieldwise и vimdiff показывает дифференциал, но не позволяет выбрать. Любая поддержка inbuild есть или нужна ли она для замены с помощью sed + awk?

+0

Вы не сможете сделать это с помощью скрипта. Или вы можете, но это будет смехотворно сложно. Вам понадобится полный скриптовый язык и синтаксический анализатор XML. Я голосую, чтобы перенести это на [так]. – terdon

+0

Какова структура документов xml? Существуют ли другие элементы в дополнение к ''? Как вы сопоставляете элементы из base.xml и new.xml? По их заказу? (то есть 1-й элемент из base.xml соответствует 1-му элементу из new.xml и т. д.) – jfs

+0

Да, есть еще элементы, а также тип . Отображение должно происходить на основе имени элемента, например, «ind» здесь, например, в приведенном выше примере. – user1587504

ответ

0

Вот прямая реализация в Python:

#!/usr/bin/env python 
# Python 2.5+ compatible 
import sys 
import xml.etree.ElementTree as etree 

def main(): 
    output_file = getattr(sys.stdout, 'buffer', sys.stdout) 
    dict2xml(merge_dicts(*map(xml2dict, sys.argv[1:])), output_file) 

def xml2dict(source): 
    return dict((el.get('name'), el.attrib) 
       for el in etree.parse(source).getiterator('element')) 

def merge_dicts(base, new): 
    merged = {} 
    # for each element from new xml 
    for name, attr in new.items(): 
     # combine attributes from base and new xmls preferring new values 
     d = merged[name] = base.get(name, {}) 
     d.update(attr) 
    return merged 

def dict2xml(d, sink): 
    root = etree.Element('root') 
    for name, attr in d.items(): 
     etree.SubElement(root, 'element', attr) 
    etree.ElementTree(root).write(sink, encoding='utf-8') 

main() 

Сохранить этот код merge-xml файл и запустить chmod +x merge-xml. Тогда:

$ ./merge-xml base.xml new.xml >merge.xml 

Вот Python 2.4+ совместимая версия:

#!/usr/bin/env python 
import sys 
from xml.dom import minidom 

def main(): 
    output_file = getattr(sys.stdout, 'buffer', sys.stdout) 
    dict2xml(merge_dicts(*map(xml2dict, sys.argv[1:])), output_file) 

def xml2dict(source): 
    doc = minidom.parse(source) 
    return dict((el.getAttribute('name'), attr2dict(el.attributes)) 
       for el in doc.getElementsByTagName('element')) 

def attr2dict(nodemap): 
    d = {} 
    for i in range(nodemap.length): 
     attr = nodemap.item(i) 
     d[attr.name] = attr.value 
    return d 

def merge_dicts(base, new): 
    merged = {} 
    # for each element from new xml 
    for name, attr in new.items(): 
     # combine attributes from base and new xmls preferring new values 
     d = merged[name] = base.get(name, {}) 
     d.update(attr) 
    return merged 

def dict2xml(d, sink): 
    doc = minidom.getDOMImplementation().createDocument(None, "root", None) 
    root = doc.documentElement 
    for name, attr in d.items(): 
     el = doc.createElement('element') 
     for name, value in attr.items(): 
      el.setAttribute(name, value) 
     root.appendChild(el) 
    sink.write(doc.toprettyxml(encoding='utf-8')) 

main() 
+0

Я попытался с выше питона скрипт, но я получаю: Файл "./merge-xml", строка 10 для эш в etree.parse (источник) .iter ('элемент')}^ SyntaxError: неверный синтаксис $ Ls/USR/бен/питон /USR/бен/питон * – user1587504

+0

использования python2.7 для запуска сценария – jfs

+0

я мог видеть 2.4 версии этого и я попробовал: #!/USR/бен/окр/usr/bin/python2.4 в первой строке вашего скрипта и все еще видят ту же ошибку. Мне нужно подождать, пока не будет установлено 2.7, если эта версия предназначена для запуска скрипта в моей рабочей управляемой среде. – user1587504

Смежные вопросы