Frage

Ich habe eine kleine Funktion geschrieben, die ElementTree und XPath verwendet die Textinhalte bestimmter Elemente in einer XML-Datei zu extrahieren:

#!/usr/bin/env python2.5

import doctest
from xml.etree import ElementTree
from StringIO import StringIO

def parse_xml_etree(sin, xpath):
  """
Takes as input a stream containing XML and an XPath expression.
Applies the XPath expression to the XML and returns a generator
yielding the text contents of each element returned.

>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem1').next()
'one'
>>> parse_xml_etree(
...   StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'),
...   '//elem2').next()
'two'
>>> parse_xml_etree(
...   StringIO('<test><null>&#0;</null><elem3>three</elem3></test>'),
...   '//elem2').next()
'three'
"""

  tree = ElementTree.parse(sin)
  for element in tree.findall(xpath):
    yield element.text  

if __name__ == '__main__':
  doctest.testmod(verbose=True)

Der dritte Test nicht besteht, mit folgenden Ausnahme:

ExpatError: Bezugnahme auf ungültige Zeichennummer: Zeile 1, Spalte 13

Ist die &#0; Einheit illegal XML? Egal, ob es oder nicht, die Dateien, die ich zu parsen will enthalten, und ich brauche einigen Weg, um sie zu analysieren. Irgendwelche Vorschläge für einen anderen Parser als Expat oder Einstellungen für Expat, die mir erlauben, das zu tun?


Update: Ich entdeckte BeautifulSoup gerade jetzt, ein Tag Suppe Parser, wie unten in der festgestellt Antwort Kommentar und für Spaß ging ich zurück zu diesem Problem und versuchte, es als XML-Reiniger vor ElementTree zu verwenden, aber es konvertierte pflichtschuldigst die &#0; in einen just-as-ungültig null-Byte. : -)

cleaned_s = StringIO(
  BeautifulStoneSoup('<test><null>&#0;</null><elem3>three</elem3></test>',
                     convertEntities=BeautifulStoneSoup.XML_ENTITIES
  ).renderContents()
)
tree = ElementTree.parse(cleaned_s)

... Ausbeuten

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12

In meinem speziellen Fall aber ich habe nicht wirklich brauchen, die XPath-Syntaxanalyse als solche ich mit BeautifulSoup gegangen sein könnte selbst und seine ganz einfachen Knoten Adressieren Stil parsed_tree.test.elem1.contents[0].

War es hilfreich?

Lösung

&#0; ist nicht in dem Rechtscharakter Bereich von der XML-Spezifikation definiert . Ach, meine Python Fähigkeiten sind ziemlich rudimentär, so dass ich es nicht viel Hilfe bin.

Andere Tipps

&#0; ist kein gültiges XML-Zeichen. Idealerweise würden Sie in der Lage sein, den Ersteller der Datei, um ihre Verfahren zu ändern, so dass die Datei wie diese nicht ungültig war.

Wenn Sie diese Dateien akzeptieren müssen, können Sie sie Vorprozess &#0 in etwas anderes zu verwandeln. Zum Beispiel, Pick @ als Escape-Zeichen, drehen "@" in "@@" und "&#0;" in "@ 0".

Dann, wie Sie die Textdaten aus dem Parser zu erhalten, können Sie die Zuordnung rückgängig machen. Dies ist nur ein Beispiel, können Sie erfinden die entweichende Syntax Sie wie.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top