Редактирование всего текста в дочерних узлах XML-файла с помощью Python - PullRequest
2 голосов
/ 08 апреля 2011

Я пытаюсь отредактировать текст внутри всех тегов с именем «Volume» в XML-файле, умножив этот текст на число, введенное пользователем. Текст внутри тега «Громкость» всегда будет числом. Мой код работает до сих пор, но только на первом экземпляре текста «Объем».

Вот пример XML:

         <blah>
                <moreblah> sometext </moreblah> ;
                <blah2>
                        <blah3> <blah4> 30 </blah4> <Volume> 15 </Volume> </blah3>
                </blah2>
        </blah>

         <blah>
                <moreblah> sometext </moreblah> ;
                <blah2>
                        <blah3> <blah4> 30 </blah4> <Volume> 25 </Volume> </blah3>
                </blah2>
        </blah>

А вот мой код Python:

#import modules
import xml.dom.minidom
from xml.dom.minidom import parse
import os
import fileinput

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

#find all instances of "Volume"
doc = parse(old_file_name)
volume = doc.getElementsByTagName('Volume')[0]
child = volume.childNodes[0]
txt = child.nodeValue

#ask for percentage input
print
percentage = raw_input("Set Volume Percentage (1 - 100): ")
if percentage.isdigit():
    if int(percentage) <101 >1:
        print 'Thank You'

        #append text of <Volume> tag
        child.nodeValue = str(int(float(txt) * (int(percentage)/100.0)))

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

        #remove XML Declaration
        text = open("blah.xml", "r").read()
        text = text.replace('<?xml version="1.0" ?>', '')  
        open("blah.xml", "w").write(text)


    else:

        print
        print 'Please enter a number between 1 and 100.'
        print 
        print 'Try again.'
        print
        print 'Exiting.'


        xml_file = open(new_file_name, "w")
        doc.writexml(xml_file)
        xml_file.close()

        os.remove(old_file_name)

Я знаю, что в моем коде у меня есть "doc.getElementsByTagName ('Volume') [0]", который обозначает первый экземпляр тега "Volume", но я просто делал это в качестве теста, чтобы увидеть, если он должно сработать. Так что я знаю, что код работает именно так, как и должно. Но мне интересно, есть ли у кого-нибудь какие-либо предложения, или он мог бы подсказать, как проще всего применить процент ввода пользователя к всем экземплярам тега "Громкость".

Это также моя первая попытка Python, поэтому, если вы видите что-то еще, что кажется странным, пожалуйста, дайте мне знать.

Спасибо за вашу помощь!

1 Ответ

2 голосов
/ 08 апреля 2011

Вы будете намного счастливее, если будете использовать более современный XML API, такой как ElementTree (в стандартной библиотеке) или lxml (более продвинутый).

В ElementTree или lxml вы получаете доступ к XPath (или чему-то близкому), что обеспечивает гораздо более гибкий синтаксис при поиске элементов и атрибутов в документах XML.

В ElementTree:

volumes = my_parsed_xml_file.find('.//Volume')

... найдет все вхождения элемента Volume.

Если вы придерживаетесь текущего синтаксиса, выполните:

doc.getElementsByTagName('Volume')[0]

... вы специально спрашиваете о нулевом (первом) Volume. Если вы хотите обработать их все, вам нужен цикл:

for volume in doc.getElementsByTagName('Volume'):
  child = volume.childNodes[0]
  // ... rest of your code inside the loop

Если такие конструкции, как циклы, вам незнакомы, вам, вероятно, следует отступить назад и прочитать вводное руководство по программированию, поскольку все станет довольно сложно без каких-либо основ. Желаем удачи!

...