2016-11-16 2 views
0

У меня есть следующий код, чтобы попытаться проанализировать XML-файл, который он читает из внешних текстовых файлов (если найден) и вставляет его содержимое во вновь введенные теги и сохраняет новый XML-код файл с результирующими манипуляциями.Как вставить текст из файла в новые теги XML

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

try: 
    import xml.etree.cElementTree as ET 
except ImportError: 
    import xml.etree.ElementTree as ET 
import os 

# define our data file 
data_file = 'test2_of_2016-09-19.xml' 

tree = ET.ElementTree(file=data_file) 
root = tree.getroot() 

for element in root: 
    if element.find('File_directory') is not None: 
     directory = element.find('File_directory').text 
    if element.find('Introduction') is not None: 
     introduction = element.find('Introduction').text 
    if element.find('Directions') is not None: 
     directions = element.find('Directions').text 

for element in root: 
    if element.find('File_directory') is not None: 
     if element.find('Introduction') is not None: 
      intro_tree = directory+introduction 
      with open(intro_tree, 'r') as f: 
       intro_text = f.read() 
      f.closed 
      intro_body = ET.SubElement(element,'Introduction_Body') 
      intro_body.text = intro_text 
     if element.find('Directions') is not None: 
      directions_tree = directory+directions 
      with open(directions_tree, 'r') as f: 
       directions_text = f.read() 
      f.closed 
      directions_body = ET.SubElement(element,'Directions_Body') 
      directions_body.text = directions_text 

tree.write('new_' + data_file) 

Проблема заключается в том, что кажется, последний нашел экземпляр file_directory, внедрения и направления сохраняется и распространяться на несколько записей, которые не желательно, поскольку каждый запись имеет свой собственный индивидуальный отчет, так сказать.

Исходный XML-файл выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Row> 
     <Entry_No>1</Entry_No> 
     <Waterfall_Name>Bridalveil Fall</Waterfall_Name> 
     <File_directory>./waterfall_writeups/1_Bridalveil_Fall/</File_directory> 
     <Introduction>introduction-bridalveil-fall.html</Introduction> 
     <Directions>directions-bridalveil-fall.html</Directions> 
    </Row> 
    <Row> 
     <Entry_No>52</Entry_No> 
     <Waterfall_Name>Switzer Falls</Waterfall_Name> 
     <File_directory>./waterfall_writeups/52_Switzer_Falls/</File_directory> 
     <Introduction>introduction-switzer-falls.html</Introduction> 
     <Directions>directions-switzer-falls.html</Directions> 
    </Row> 
</Root> 

Нужный выход XML должен выглядеть следующим образом:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Row> 
     <Entry_No>1</Entry_No> 
     <Waterfall_Name>Bridalveil Fall</Waterfall_Name> 
     <File_directory>./waterfall_writeups/1_Bridalveil_Fall/</File_directory> 
     <Introduction>introduction-bridalveil-fall.html</Introduction> 
     <Directions>directions-bridalveil-fall.html</Directions> 
     <Introduction_Body>Text from ./waterfall_writeups/1_Bridalveil_Fall/introduction-bridalveil-fall.html</Introduction_Body> 
     <Directions_Body>Text from ./waterfall_writeups/1_Bridalveil_Fall/directions-bridalveil-fall.html</Directions_Body> 
    </Row> 
    <Row> 
     <Entry_No>52</Entry_No> 
     <Waterfall_Name>Switzer Falls</Waterfall_Name> 
     <File_directory>./waterfall_writeups/52_Switzer_Falls/</File_directory> 
     <Introduction>introduction-switzer-falls.html</Introduction> 
     <Directions>directions-switzer-falls.html</Directions> 
     <Introduction_Body>Text from ./waterfall_writeups/52_Switzer_Falls/introduction-switzer-falls.html</Introduction_Body> 
     <Directions_Body>Text from ./waterfall_writeups/52_Switzer_Falls/directions-switzer-falls.html</Directions_Body> 
    </Row> 
</Root> 

Но то, что я в конечном итоге получаю:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Row> 
     <Entry_No>1</Entry_No> 
     <Waterfall_Name>Bridalveil Fall</Waterfall_Name> 
     <File_directory>./waterfall_writeups/1_Bridalveil_Fall/</File_directory> 
     <Introduction>introduction-bridalveil-fall.html</Introduction> 
     <Directions>directions-bridalveil-fall.html</Directions> 
     <Introduction_Body>Text from ./waterfall_writeups/52_Switzer_Falls/introduction-switzer-falls.html</Introduction_Body> 
     <Directions_Body>Text from ./waterfall_writeups/52_Switzer_Falls/directions-switzer-falls.html</Directions_Body> 
    </Row> 
    <Row> 
     <Entry_No>52</Entry_No> 
     <Waterfall_Name>Switzer Falls</Waterfall_Name> 
     <File_directory>./waterfall_writeups/52_Switzer_Falls/</File_directory> 
     <Introduction>introduction-switzer-falls.html</Introduction> 
     <Directions>directions-switzer-falls.html</Directions> 
     <Introduction_Body>Text from ./waterfall_writeups/52_Switzer_Falls/introduction-switzer-falls.html</Introduction_Body> 
     <Directions_Body>Text from ./waterfall_writeups/52_Switzer_Falls/directions-switzer-falls.html</Directions_Body> 
    </Row> 
</Root> 

В стороне, есть ли способ ввести содержимое тегов тела без его распечатывания на одной строке (для readab ility)?

ответ

0

Первые for итерацию цикла по элементам документа, назначая новые значения для ваших directory, introduction и directions переменных соответственно, с каждой итерацией, в конечном итоге со значениями из последних происходящих элемента.

Что я хотел бы сделать, это создать словарь , чтобы отобразить имена тегов в текстовое содержимое, а затем использовать это сопоставление для добавления новых подэлементов на лету. Пример (без чтения ссылочных файлов):

for row in root: 
    elements = {} 
    for node in row: 
     elements[node.tag] = node.text 

    directory = elements['File_directory'] 

    intro_tree = directory + elements['Introduction'] 
    intro_body = ET.SubElement(row, 'Introduction_Body') 
    intro_body.text = 'Text from %s' % intro_tree 

    directions_tree = directory + elements['Directions'] 
    directions_body = ET.SubElement(row, 'Directions_Body') 
    directions_body.text = 'Text from %s' % directions_tree 
+0

Спасибо за ответ. Оказывается, я узнал, что я сделал не так, и исправил его, изменив порядок выполнения циклов, но создание словаря, как вы предложили, имеет смысл. – Johnny

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