Предполагая, что требуется правильный XML синтаксический анализ, предлагая разбить проблему на несколько шагов - python * Преобразование каждой записи "HITS" XML в (python) словарь * Группировка словарей по RE C , нахождение максимального приоритета, количество * Группировка RECS по приоритету, нахождение количества (попаданий), количества (записей)
Шаг 1 и 2 могут быть объединены вместе, шаг № 3 должен быть выполнен как отдельный проход (это не снимите вопрос OP, если гарантируется, что данные будут отсортированы по RE C).
Для шага # 1 лучше использовать SAX-анализатор (на основе событий), чтобы избежать загрузки всего набора данных в память.
Я считаю, что шаги 2 и 3 могут быть лучше реализованы. Я все еще в процессе перехода на Python. Рассмотрим реализацию ниже как эффективную отправную точку
#! /usr/bin/python
import xml.sax
debug = False
class recItem:
def __init__ (self):
self.count = 0
self.maxPri = None
# Dictionary by REC of recItem
recData = {}
class dataHandler (xml.sax.ContentHandler):
def __init__ (self):
self.lastTag = ""
self.data = None
def startElement(self, tag, attribute):
if ( debug ):
print "S", self, tag, attribute
self.lastTag = tag
if tag == "HITS":
self.data = { "HITS": "", "REC": "", "PRIORITY": "" }
def characters(self, content):
if ( debug ):
print "C", self, self.lastTag, content
if ( self.data != None and self.lastTag in self.data ):
self.data[self.lastTag] += content
def endElement(self, tag):
if ( debug ):
print "E", self, tag
self.lastTag = None
if ( tag == "HITS" ) :
rec = self.data["REC"]
priority = int(self.data["PRIORITY"])
hits = self.data["HITS"]
# Find priority by rec
if ( rec in recData ):
# Find max priority
if ( priority > recData[rec].maxPri ):
recData[rec].maxPri = priority
else:
# New REC
item = recItem();
item.maxPri = priority ;
recData[rec] = item
recData[rec].count += 1
self.data = None
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
parser.setContentHandler(dataHandler())
parser.parse("data.xml")
if ( debug ):
for k, v in recData.items():
print k, v.maxPri, v.count
Шаг # 3
class priItem:
def __init__ (self):
self.hits = 0
self.recs = 0
# Group REC by priority
priData = {}
for k, v in recData.items():
priEntry = priData[v.maxPri] if v.maxPri in priData else None
if ( priEntry == None ):
priEntry = priData[v.maxPri] = priItem()
priEntry.hits += v.count
priEntry.recs += 1
# Print final output
print "PRIORITY", "REC", "HITS"
for k, v in priData.items():
print k, v.recs, v.hits
Вывод (соответствует запросу OP), может быть отформатирован в CSV или аналогичен, если необходимо.
PRIORITY REC HITS
1 3 6
-1 1 2