2011-12-30 5 views
0

Мой код почти закончен, но у меня возникают проблемы с разделением SubElements в цикле for (?). Как я могу получить каждый элемент в свой собственный в xml корневой узел?Разделить субэлементы в цикле `for` с использованием Python и XML

import csv 
import sys 

from xml.etree import ElementTree 
from xml.etree.ElementTree import Element, SubElement, Comment, tostring 

from xml.dom import minidom 

def prettify(elem): 
    """Return a pretty-printed XML string for the Element. 
    """ 
    rough_string = ElementTree.tostring(elem, 'utf-8') 
    reparsed = minidom.parseString(rough_string) 
    return reparsed.toprettyxml(indent=" ") 

xml = '<?xml version="1.0" encoding="utf-8"?>' 
doctype = '<!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd">' 
root = Element('smil') 
root.set('xmlns', 'http://www.w3.org/2001/SMIL20/Language')    
head = SubElement(root, 'head') 
meta = SubElement(head, 'meta base="rtmp://cp23636.edgefcs.net/ondemand"') 
body = SubElement(root, 'body') 

video_data = ((256, 336000), 
       (512, 592000), 
       (768, 848000), 
       (1128, 1208000)) 

with open(sys.argv[1], 'rU') as f: 
    reader = csv.DictReader(f) 
    for row in reader: 
     switch_tag = ElementTree.SubElement(body, 'switch') 

     for suffix, bitrate in video_data: 
      attrs = {'src': ("mp4:soundcheck/{year}/{id}/{file_root_name}_{suffix}.mp4" 
          .format(suffix=str(suffix), **row)), 
        'system-bitrate': str(bitrate), 
        } 
      ElementTree.SubElement(switch_tag, 'video', attrs) 

print xml + doctype + prettify(root) 

возвращается:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd"><?xml version="1.0" ?> 
<smil xmlns="http://www.w3.org/2001/SMIL20/Language"> 
    <head> 
    <meta base="rtmp://cp23636.edgefcs.net/ondemand"/> 
    </head> 
    <body> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/04_sc_ca_thousandda_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/04_sc_ca_thousandda_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/04_sc_ca_thousandda_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/04_sc_ca_thousandda_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/05_sc_ca_hereyoucom_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/05_sc_ca_hereyoucom_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/05_sc_ca_hereyoucom_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/05_sc_ca_hereyoucom_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/06_sc_ca_intv_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/06_sc_ca_intv_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/06_sc_ca_intv_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/06_sc_ca_intv_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    </body> 
</smil> 

Но то, что я хочу, чтобы каждый элемент был сам по себе. Как это:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd"><?xml version="1.0" ?> 
<smil xmlns="http://www.w3.org/2001/SMIL20/Language"> 
    <head> 
    <meta base="rtmp://cp23636.edgefcs.net/ondemand"/> 
    </head> 
    <body> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    </body> 
</smil> 

и

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd"><?xml version="1.0" ?> 
<smil xmlns="http://www.w3.org/2001/SMIL20/Language"> 
    <head> 
    <meta base="rtmp://cp23636.edgefcs.net/ondemand"/> 
    </head> 
    <body> 
    <switch> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_256.mp4" system-bitrate="336000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_512.mp4" system-bitrate="592000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_768.mp4" system-bitrate="848000"/> 
     <video src="mp4:soundcheck/1/clay_aiken/03_sc_ca_everything_1128.mp4" system-bitrate="1208000"/> 
    </switch> 
    </body> 
</smil> 

ответ

2

Как это?

import csv 
import sys 

from xml.etree import ElementTree 
from xml.etree.ElementTree import Element, SubElement, Comment, tostring 

from xml.dom import minidom 

def prettify(doctype, elem): 
    """Return a pretty-printed XML string for the Element. 
    """ 
    rough_string = doctype + ElementTree.tostring(elem, 'utf-8') 
    reparsed = minidom.parseString(rough_string) 
    return reparsed.toprettyxml(indent=" ", encoding = 'utf-8') 

doctype = '<!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd">' 

video_data = ((256, 336000), 
       (512, 592000), 
       (768, 848000), 
       (1128, 1208000)) 

with open(sys.argv[1], 'rU') as f: 
    reader = csv.DictReader(f) 
    for row in reader: 
     root = Element('smil') 
     root.set('xmlns', 'http://www.w3.org/2001/SMIL20/Language') 
     head = SubElement(root, 'head') 
     meta = SubElement(head, 'meta base="rtmp://cp23636.edgefcs.net/ondemand"') 
     body = SubElement(root, 'body') 

     switch_tag = ElementTree.SubElement(body, 'switch') 

     for suffix, bitrate in video_data: 
      attrs = {'src': ("mp4:soundcheck/{year}/{id}/{file_root_name}_{suffix}.mp4" 
          .format(suffix=str(suffix), **row)), 
        'system-bitrate': str(bitrate), 
        } 
      ElementTree.SubElement(switch_tag, 'video', attrs) 

     print prettify(doctype, root) 
+0

Спасибо! Вот и все. Он возвращает '' Как я могу получить DOCTYPE во второй строке и удалить дублируемую строку версии xml? –

+1

Я отредактировал, чтобы удалить «print xml» и вместо этого использовать для этого toprettyxml. Теперь есть способы порезать строку и поместить там 'DOCTYPE', но позвольте мне посмотреть, можем ли мы это сделать, используя' ElementTree' ... вместо этого ... –

+1

Хорошо, это немного клочья, но делает то, что вы хотеть. Вставка 'DOCTYPE' правильного пути требует подкласса' ElementTree.TreeBuilder', чтобы добавить метод 'doctype', и это немного выходит за рамки этого вопроса :) –

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