В Python — анализ XML-ответа и поиск определенного текстового поля

#python #xml #parsing #memory

#python #xml #синтаксический анализ #память

Вопрос:

Я новичок в python, и мне особенно сложно работать с xml и python. Ситуация, с которой я столкнулся, такова: я пытаюсь подсчитать, сколько раз слово появляется в XML-документе. Достаточно просто, но XML-документ является ответом от сервера. Возможно ли это сделать без записи в файл? Было бы здорово попытаться сделать это из памяти.

Вот пример XML-кода:

 <xml>
  <title>Info</title>
    <foo>aldfj</foo>
      <data>Text I want to count</data>
</xml>
  

Вот что у меня есть в python

 import urllib2
import StringIO
import xml.dom.minidom
from xml.etree.ElementTree import parse
usock = urllib.urlopen('http://www.example.com/file.xml') 
xmldoc = minidom.parse(usock)
print xmldoc.toxml()
  

После этого я безуспешно пытался использовать StringIO, ElementTree и minidom, и я дошел до того, что не уверен, что еще делать.

Любая помощь будет с благодарностью

Ответ №1:

Насколько я могу судить, это довольно просто:

 import urllib2
from xml.dom import minidom

usock = urllib2.urlopen('http://www.example.com/file.xml') 
xmldoc = minidom.parse(usock)

for element in xmldoc.getElementsByTagName('data'):
  print element.firstChild.nodeValue
  

Итак, чтобы подсчитать вхождения строки, попробуйте это (немного сжато, но мне нравятся однострочники):

 count = sum(element.firstChild.nodeValue.find('substring') for element in xmldoc.getElementsByTagName('data'))
  

Ответ №2:

Если вы просто пытаетесь подсчитать, сколько раз слово появляется в XML-документе, просто прочитайте документ как строку и выполните подсчет:

 import urllib2
data = urllib2.urlopen('http://www.example.com/file.xml').read()
print data.count('foobar')
  

В противном случае вы можете просто перебирать теги, которые вы ищете:

 from xml.etree import cElementTree as ET
xml = ET.fromstring(urllib2.urlopen('http://www.example.com/file.xml').read())
for data in xml.getiterator('data'):
    # do something with
    data.text
  

Комментарии:

1. Из вопроса ясно, что он хочет подсчитывать слова только в определенном теге. Вы также не можете быть уверены, что слово фактически не используется в качестве самого тега, поэтому такой подход явно неверен

2. Хотя это работает для некоторых слов, оно терпит неудачу при наличии объектов XML.

3. вау, я должен был получить это. Возможно, я мог бы использовать это, поскольку XML-ответ не является повторяющимся

4. Боже, сегодня много ненависти. В OP указано, что он «пытается подсчитать, сколько раз слово появляется в документе xml». Я изменил строку count, чтобы она не совпадала с примером тега, который он привел.

5. @DerekSpringer не ненавижу … но использование простого count() в XML-документе явно опасно и может привести к неправильным ответам… и вы не будете знать, когда они ошибаются… отсюда и решительный комментарий

Ответ №3:

Помогает ли это…

 from xml.etree.ElementTree import XML

txt = """<xml>
           <title>Info</title>
           <foo>aldfj</foo>
           <data>Text I want to count</data>
         </xml>"""

# this will give us the contents of the data tag.
data = XML(txt).find("data").text

# ... so here we could do whatever we want
print data
  

Комментарии:

1. Нет, он получает только один конкретный текст, а не все текстовые узлы.

2. Я не выполняю всю его домашнюю работу… оттуда он может самостоятельно использовать findall …

Ответ №4:

Просто замените строку ‘count’ любым словом, которое вы хотите посчитать. Если вы хотите подсчитать фразы, вам придется адаптировать этот код, поскольку он предназначен для подсчета слов. Но в любом случае, ответ на вопрос, как получить вообще встроенный текст, таков XML('<your xml string here>').itertext()

 from xml.etree.ElementTree import XML
from re import findall

txt = """<xml>
        <title>Info</title>
        <foo>aldfj</foo>
        <data>Text I want to count</data>
    </xml>"""

sum([len(filter(lambda w: w == 'count', findall('w ', t))) for t in XML(txt).itertext()])