2015-05-22 2 views
-4

У меня есть несколько XML-файлов (60+), которые мне нужны для редактирования нескольких текстовых узлов (я думаю, это называется). Я знаком с Java, JavaScript, Python, JQuery, PHP, HTML.Редактирование нескольких XML-узлов в нескольких XML-файлах

На каком языке я могу это завершить?

Это то, что я тока есть для образца XML документ:

<?xml version="1.0" encoding="utf-8"?><bookstore> 
    <book category="cooking"> 
     <title lang="en">Chinese</title> 
     <author>chinese author</author> 
     <year>2015</year> 
     <price>fourth</price> 
    </book> 
    <book category="cooking"> 
     <title lang="en">All American</title> 
     <author>American Author</author> 
     <year>2015</year> 
     <price>6.00</price> 
    </book> 
</bookstore> 

Так, например, я хочу, чтобы изменить автора и год нескольких элементов сразу!

Это мой код python, который будет редактировать один узел за раз. Мне нужен цикл или что-то, чтобы редактировать больше сразу.

from xml.dom.minidom import parse 
import os 

# create a backup of original file 
new_file_name = 'dom.xml' 
old_file_name = new_file_name + "~" 
os.rename(new_file_name, old_file_name) 

# change text value of element 
doc = parse(old_file_name) 
node = doc.getElementsByTagName('author') 
node[0].firstChild.nodeValue = 'new author' 


# persist changes to new file 
xml_file = open(new_file_name, "w") 
doc.writexml(xml_file, encoding="utf-8") 
xml_file.close() 

Любая помощь была бы принята с благодарностью. Начинающий программист!

СПАСИБО! : D

+0

Вы хотите изменить автора, буквально, 'новый автор' в каждой книге в каждом файле? Или вы хотите изменить кого-то на «новый автор», а не на других? Или некоторые из «новых других» и некоторых других «другому новому автору»? –

+0

«новый автор» - это просто место (очевидно). Мне нужны некоторые изменения, но не все. Однако знать оба пути было бы неплохо. Это все фиктивные данные. У меня гораздо больше файлов, на которые это действительно нужно применить. – Kevin

+0

Если вы просто хотите использовать лучший инструмент для задания - как следует из вашего первого абзаца, а не для Python, я бы избегал помечать этот питон (точно так же отмечая «как мне сделать X из оболочки» с помощью awk и sed, потому что один думает, что один из этих инструментов может быть удобным, нахмурился). Аналогичным образом, если вы хотите повторно использовать стороннюю библиотеку вместо написания собственного анализатора, это не вопрос синтаксического анализа. –

ответ

0

Создание функций:

def create_backup(new_file_name): 
    """ create a backup of original file """ 
    old_file_name = new_file_name + "~" 
    os.rename(new_file_name, old_file_name) 
    return old_file_name 

def change_author(doc, new_author) 
    """ change text value of 'author' """ 
    node = doc.getElementsByTagName('author') 
    node[0].firstChild.nodeValue = new_author 

def save_changes(new_file_name, doc): 
    """ persist changes to new file """ 
    xml_file = open(new_file_name, "w") 
    doc.writexml(xml_file, encoding="utf-8") 
    xml_file.close() 

А теперь это легко создать цикл:

file_names = ['dom.xml', ...] 
for new_file_name in file_names: 
    old_file_name = create_backup(new_file_name) 
    doc = parse(old_file_name) 
    change_author(doc, 'new author') 
    save_changes(new_file_name, doc) 
+0

Итак, если бы я хотел редактировать разные элементы или узлы, я бы просто добавил для него еще одну функцию, а затем, а затем назовет ее в конце перед сохранением изменений? – Kevin

+0

Да, это так. –

0

Лично я хотел бы сделать это с помощью сценария оболочки и XMLStarlet.

for f in *.xml; do 
    xmlstarlet ed \ 
    -u '//author' -v 'new author' \ 
    <"$f" >"$f.new" && mv "$f.new" "$f" 
done 

Если вы хотите изменить автор для книги «Всех американской», а также изменить цену на ту же книгу, это может быть вместо этого:

for f in *.xml; do 
    xmlstarlet ed \ 
    -u '//book[title="All American"]/author' -v 'new author' \ 
    -u '//book[title="All American"]/price' -v 12.34 \ 
    <"$f" >"$f.new" && mv "$f.new" "$f" 
done 

Обратите внимание, что при использовании жёстко временные имена файлов являются плохой практикой, если любые другие пользователи могут писать в каталог, который вы используете; должно быть так, использование mktemp для создания уникального временного имени файла было бы более уместным.

+0

Никогда не использовал ни один из них. Как мне настроить настройку среды? – Kevin

+0

В значительной степени зависит от вашей операционной системы и среды. Если вы используете Mac с установленными MacPorts, это 'sudo port install xmlstarlet'; на Ubuntu это будет 'sudo apt-get install xmlstarlet' и т. д. и т. д., поскольку локальный способ установки программного обеспечения находится в ОС, которую вы сейчас используете. –

+0

... как для 'mktemp', это входит в комплект поставки с любой современной Unix. –