Могу ли я как-то сказать парсеру SAX остановиться на каком-то элементе и получить его дочерние узлы в виде строки? - PullRequest
3 голосов
/ 05 января 2012

У меня довольно большие XML-документы, поэтому я не хочу использовать DOM, но при разборе документа с помощью SAX-анализатора я хочу остановиться в какой-то момент (скажем, когда я достиг элемента с определенным именем) и получить всевнутри этого элемента в виде строки.«Все» внутри не обязательно является текстовым узлом, он может содержать теги, но я не хочу, чтобы они анализировались, я просто хочу получить их как текст.

Я пишу на Python.Возможно ли решить?Спасибо!

Ответы [ 3 ]

1 голос
/ 05 января 2012

Я не верю, что это возможно с xml.sax. BeautifulSoup имеет SoupStrainer, который делает именно это. Если вы открыты для использования библиотеки, с ней довольно легко работать.

0 голосов
/ 26 августа 2012

Вот хакерский способ сделать это, используя SAX.Это будет держать содержимое внутри ваших текстовых узлов.Однако все усложняется, если вам нужно хранить теги и атрибуты внутри этих текстовых узлов.

from xml.sax import handler, make_parser

class CustomContentHandler(handler.ContentHandler):

    def __init__(self):
        handler.ContentHandler.__init__(self)
        self.inside_text_tag = False
        self.text_content = []

    def startElement(self, name, attrs):
        if name == 'text':
            self.inside_text_tag = True

    def endElement(self, name):
        if name == 'text':
            self.inside_text_tag = False
            self.text = ''.join(self.text_content)
            print "%s" % (self.text)

    def characters(self, content):        
        if self.inside_text_tag:
            self.text_content.append(content)

def parse_file(filename):
    f = open(filename)
    parser = make_parser()
    ch = CustomContentHandler()
    parser.setContentHandler(ch)
    parser.parse(f)
    f.close()

if __name__ == "__main__":
    filename = "sample.xml"
    parse_file(filename)

При использовании со следующим файлом sample.xml:

<tag1>
  <tag2>
    <title>XML</title>
    <text>
      Text001
      <h1>Header</h1>
      Text002
      <b>Text003</b>
    </text>
  </tag2>
</tag1>

даст

Text001
Header
Text002
Text003
0 голосов
/ 05 января 2012

Для этого предназначены разделы CDATA.

http://www.w3schools.com/xml/xml_cdata.asp

Для правильной обработки разделов CDATA можно использовать libxml_saxlib.ОБНОВЛЕНИЕ: как строго временное решение, вы можете предварительно обработать ваш входной файл, чтобы сделать его действительным XML.Используйте «sed», например, для вставки тегов CDATA в соответствующие места.

Это не решает реальную проблему, но дает вам файл XML для анализа, если вам повезет (например, вне XML-часть файла ...).

...