2015-04-13 2 views
1

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

Код написан на python.

settings = XmlReaderSettings() 
settings.DtdProcessing = DtdProcessing.Ignore 

reader = XmlReader.Create(DXFfile, settings) 

while reader.Read(): 
    if reader.NodeType == XmlNodeType.Element: 
     if reader.Name=="NAME": 
      reader.Read() 
      plog(reader.Value + "\n"); 

Это дает мне следующее сообщение об ошибке, как только я запускаю его:

XmlException: данные на корневом уровне является недействительным. Строка 1, позиция 3.

Вот XML часть редактируемого файла:

0 
EMPORT 
    999 
<PORTLIST><HPORT><NAME>PORT TEST</NAME></HPORT></PORTLIST> 
    0 
SEQEND 
+0

Не использовать XmlReader до тех пор, пока вы уже уверен, что вы читаете XML-контент. Если ничего больше не начнется с '<', используйте эту информацию. –

+0

Я также настоятельно рекомендую использовать более современную библиотеку XML - 'lxml.etree', или ElementTree, если придерживаться стандартной библиотеки и т. Д. Любой из них сделает операции' tostring() 'и' fromstring() 'тривиальными , –

+0

@CharlesDuffy Где я могу найти документацию для этих библиотек? Я хотел немного изменить библиотеку, но я традиционно являюсь C++-кодером, поэтому у меня нет большого опыта в Python. – user2970916

ответ

1

Пример использования lxml:

#!/usr/bin/env python 
import lxml.etree as etree 
import sys 

input_filename = sys.argv[1] 
output_filename = sys.argv[2] 

output_file = open(output_filename, 'w') 
for line in open(input_filename, 'r').readlines(): 
    line = line.rstrip('\n') 
    handled = False 
    if line and line[0] == '<': 
    try: 
     xml_el = etree.fromstring(line) 
     name = xml_el.find('.//NAME') 
     if name is not None: 
     print 'Found name:', name.text 
     # Add a new XML element under HPORT, and print 
     hport_el = xml_el.find('.//HPORT') 
     if hport_el is not None: 
     new_el = etree.SubElement(hport_el, 'NewElement') 
     new_el.text = 'Content Here' 
     print >>output_file, etree.tostring(xml_el) 
     handled = True 
    except lxml.etree.XMLSyntaxError: 
     pass # this line wasn't a valid standalone XML document 
    if not handled: 
    print >>output_file, line 

Важные вещи, чтобы отметить:

  • Мы читаем и пишем со стандартными линиями ввода-вывода.
  • Если мы прочитали документ XML, мы используем lxml.etree.fromstring() для десериализации его объектов DOM, lxml.etree.Element.find(), чтобы найти элемент, который мы хотим запросить внутри него, и lxml.etree.SubElement(), чтобы обновить то, что мы читаем на месте (добавление нового элемента, в этом случае). Если вы хотите изменить содержимое существующего элемента, а не добавлять новый, вы можете это сделать тривиально.
  • После того как мы обновили документ, мы используем lxml.etree.tostring(), чтобы преобразовать его обратно в строку.

Запуск

./update-xml-subsections input-file output-file 

... с вашим заданным входным файлом будет выдавать выходной файл, содержащий:

0 
EMPORT 
    999 
<PORTLIST><HPORT><NAME>PORT TEST</NAME><NewElement>Content Here</NewElement></HPORT></PORTLIST> 
    0 
SEQEND 
+0

Я ценю ответ. Я пытаюсь понять, как это сделать со встроенной библиотекой xml.etree. – user2970916

+0

Мне удалось заставить его работать с помощью библиотеки xml.etree. Видимо, в коде нет абсолютно никакой разницы. – user2970916

+0

Действительно, они очень похожи. 'lxml.etree' работает быстрее и имеет дополнительную функциональность, но я не использовал никакой дополнительной функции здесь. –

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