С помощью python lxml я хочу создать элемент etree.Element, содержимое которого взято из строки.У меня есть два случая:
- Это простая строка (например: «Hello world!»).
- Это строка с тегами, но все же, для Python это строкаи я не знаю заранее, что это помеченный (например: «Привет! ").
Как справиться со вторым случаем?
Вот наивный, не функционирующий способ:
>>> from lxml import etree
>>> string = "Hello <value-of select=\"world\"/>!"
>>> xml = etree.Element('root')
>>> xml.text = string
>>> etree.tostring(xml)
... b'<root>Hello <value-of select="world"/>!</root>'
Я хорошо знаю, что,если я знаю структуру моей строки, я должен использовать метод tail из etree.Element, как описано в учебном пособии по lxml . Итак, вот функционирующий, не обобщаемый способ:
>>> from lxml import etree
>>> xml2 = etree.Element('root')
>>> xml2.text = "Hello "
>>> valueof = etree.SubElement(xml2, 'value-of')
>>> valueof.set('select', 'world')
>>> valueof.tail = '!'
>>> etree.tostring(xml2)
... b'<root>Hello <value-of select="world"/>!</root>'
Но как сделать это автоматически, не зная заранее точную строку?
Я не знаю, как разобрать строку, чтобы можно было разбить ее части. Или, может быть, мне следует попробовать другой способ.
Я попробовал это:
>>> from lxml import etree
>>> from io import StringIO
>>> string="Hello <value-of select=\"world\"/>!"
>>> tree = etree.parse(StringIO(string))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "src/lxml/lxml.etree.pyx", line 3427, in lxml.etree.parse (src/lxml/lxml.etree.c:81117)
File "src/lxml/parser.pxi", line 1828, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:118072)
File "src/lxml/parser.pxi", line 1848, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:118341)
File "src/lxml/parser.pxi", line 1729, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:116899)
File "src/lxml/parser.pxi", line 1063, in lxml.etree._BaseParser._parseUnicodeDoc (src/lxml/lxml.etree.c:110886)
File "src/lxml/parser.pxi", line 595, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:105109)
File "src/lxml/parser.pxi", line 706, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:106817)
File "src/lxml/parser.pxi", line 635, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:105671)
File "<string>", line 1
lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1
Но так как etree.parse требует правильно сформированного xml и нет корневого элемента, он терпит неудачу. Поэтому я попробовал это, надеясь, что он будет менее строгим:
>>> tree = etree.parse(StringIO(string), etree.XMLParser(recover=True))
>>> etree.tostring(tree)
но вывод пуст, поэтому кажется, что я не могу разобрать мою строку, чтобы добавить результирующее дерево к существующему ... Именно так мне нужно делать вещи, потому что я сочиняю свой xmlс нуля.
Вернуться к моему вопросу: как справиться с двумя делами, которые япредставлен ранее?