Python: извлечение HTML из файла XML - PullRequest
0 голосов
/ 29 ноября 2009

Мой XML-файл выглядит так:

 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>

Я хочу извлечь содержимое каждого , сохраняя при этом внутренние теги. То есть я хотел бы видеть следующую строку Python: u "Bla One & Two Foo". В качестве альтернативы, я думаю, я мог бы остановиться на "Bla One & Two Foo", а затем попытаться заменить сущности самостоятельно.

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

Если возможно, я бы предпочел сохранить lxml, хотя при необходимости могу переключиться на другую библиотеку.

Ответы [ 4 ]

3 голосов
/ 29 ноября 2009

Возможно, существует лучший способ условной обработки объектов, возвращаемых функцией xpath(), но я недостаточно знаком с lxml, чтобы знать, что это такое, поэтому мне пришлось написать функцию, которая возвращает текстовое значение узла. Но, тем не менее, это показывает общий подход к проблеме:

>>> from lxml import etree
>>> from StringIO import StringIO
>>> def node_text(n):
        try:
            return etree.tostring(n, method='html', with_tail=False)
        except TypeError:
            return str(n)

>>> f = StringIO('<strings><string>This is <b>not</b> how I plan to escape.</string></strings>')
>>> x = etree.parse(f)
>>> ''.join(node_text(n) for n in x.xpath('/strings/string/node()'))
'This is <b>not</b> how I plan to escape.'
2 голосов
/ 29 ноября 2009

try etree.tostring

outer = etree.tostring(string_elem, method='html')
inner = re.match("^[^>]+>(.*)<[^<]+$", outer).groups(1)[0]
0 голосов
/ 29 ноября 2009

Не использует синтаксический анализатор, а просто чистые манипуляции со строками

mystring="""
 <strings>
      <string>Bla <b>One &amp; Two</b> Foo</string>
 </strings>
"""
for s in mystring.split("</string>"):
    if "<string>" in s:
        i = s.index("<string>")
        print s[i+len("<string>"):].replace("&amp;","")
0 голосов
/ 29 ноября 2009

Независимо от языка, относительно простой шаблон XSLT справится с задачей.

Что-то вроде определения шаблонов для тегов, которые вы хотите сохранить, преобразования в текстовые другие.

Конечно, вы можете использовать рекурсивную функцию с совместимой реализацией DOM (возможно, minidom?) И обрабатывать теги вручную.

(псевдокод)

def Function(tag):
   if tag.NodeType = "#text": return tag.innerText
   text=""
   if tag.ElementName in allowedTags:
       text="<%s>"%tag.ElementName
   text += [Function(subtag) for subtag in tag.childs]
   if tag.ElementName in allowedTags:
       text+="</%s>"%tag.ElementName
   return text
...