Вопрос

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

Есть ли способ сделать .removeChild и удалить пробелы?

Вот как выглядит мой код:

dom=parse(filename)
main=dom.childNodes[0]
sources = main.getElementsByTagName("source")
for source in sources :
    name=source.getAttribute("name")
    spatialModel=source.getElementsByTagName("spatialModel")
    val1=float(spatialModel[0].getElementsByTagName("parameter")[0].getAttribute("value"))
    val2=float(spatialModel[0].getElementsByTagName("parameter")[1].getAttribute("value"))
    if angsep(val1,val2,X,Y)>=ROI :
        main.removeChild(source)
    else:
        print name,val1,val2,angsep(val1,val2,X,Y)
f=open(outfile,"write")
f.write("<?xml version=\"1.0\" ?>\n")
f.write(dom.saveXML(main))
f.close()

Большое спасибо за помощь.

Это было полезно?

Решение 2

Я не мог понять, как это сделать с помощью xml.dom.minidom, поэтому я просто написал быструю функцию для чтения выходного файла и удаления всех пустых строк, а затем переписывания в новый файл:

f = open(xmlfile).readlines()
w = open('src_model.xml','w')
empty=re.compile('^$')
for line in open(xmlfile).readlines():
    if empty.match(line):
        continue
    else: 
        w.write(line)

Для меня это работает достаточно хорошо :)

Другие советы

Если у вас установлен PyXML, вы можете использовать xml.dom.ext.PrettyPrint().

… для поиска людей:

Этот забавный фрагмент

skey = lambda x: getattr(x, "tagName", None)
mainnode.childNodes = sorted( 
  [n for n in mainnode.childNodes if n.nodeType != n.TEXT_NODE],
  cmp=lambda x, y: cmp(skey(y), skey(x)))

удаляет все текстовые узлы (а также выполняет обратную сортировку по тэгам).

Т.е.вы можете (рекурсивно) сделать tr.childNodes = [recurseclean(n) for n in tr.childNodes if n.nodeType != n.TEXT_NODE] удалить все текстовые узлы

Или вы можете сделать что-то вроде … if n.nodeType != n.TEXT_NODE or not re.match(r'^[:whitespace:]*$', n.data, re.MULTILINE) (сам не пробовал), если вам нужны текстовые узлы с некоторыми данными.Или что-то более сложное, чтобы оставить текст внутри определенных тегов.

После этого tree.toprettyxml(…) вернет хорошо отформатированный текст XML.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top