タスクは、単純な XML ドキュメントを解析し、内容を行番号で分析することです。
正しい Python パッケージはxml.sax. しかし、どのように使用するのですか?
ドキュメントを掘り下げた後、次のことがわかりました。
xmlreader.Locatorインターフェイスには次の情報があります:getLineNumber()。handler.ContentHandlerインターフェイスにはsetDocumentHandler().
最初に考えられるのは、 を作成しLocator、これを に渡し、メソッドのContentHandler呼び出し中に Locator から情報を読み取る、などです。character()
ただし、xmlreader.Locatorはスケルトン インターフェイスにすぎず、そのメソッドのいずれからも -1 しか返せません。それで、貧弱なユーザーとして、私は何をすべきでしょうParserかLocator?
私は今、自分の質問に答えます。
(まあ、私はできないという恣意的で迷惑なルールを除いて、私は持っているでしょう。)
既存のドキュメントを使用して (または Web 検索で) これを理解することができず、xml.sax(私のシステムの /usr/lib/python2.7/xml/sax/ の下にある) のソース コードを読むことを余儀なくされました。
xml.sax関数make_parser()はデフォルトで実数を作成しますが、それParserはどのようなものですか?
ソース コードでは、ExpatParserexpatreader.py で定義されている であることがわかります。そして...それは独自のLocator、を持っていExpatLocatorます。しかし、これにはアクセスできません。これと解決策の間で多くの頭を悩ませました。
- r
ContentHandlerについて知っている独自の を作成し、それを使用して行番号を決定しますLocato ExpatParserで作成xml.sax.make_parser()- を作成し、インスタンス
ExpatLocatorに渡します。ExpatParser - を作り、
ContentHandlerこれを与えるExpatLocator ContentHandlerをパーサーに渡すsetContentHandler()- を呼び出し
parse()ますParser。
例えば:
import sys
import xml.sax
class EltHandler( xml.sax.handler.ContentHandler ):
def __init__( self, locator ):
xml.sax.handler.ContentHandler.__init__( self )
self.loc = locator
self.setDocumentLocator( self.loc )
def startElement( self, name, attrs ): pass
def endElement( self, name ): pass
def characters( self, data ):
lineNo = self.loc.getLineNumber()
print >> sys.stdout, "LINE", lineNo, data
def spit_lines( filepath ):
try:
parser = xml.sax.make_parser()
locator = xml.sax.expatreader.ExpatLocator( parser )
handler = EltHandler( locator )
parser.setContentHandler( handler )
parser.parse( filepath )
except IOError as e:
print >> sys.stderr, e
if len( sys.argv ) > 1:
filepath = sys.argv[1]
spit_lines( filepath )
else:
print >> sys.stderr, "Try providing a path to an XML file."
Martijn Pieters は、いくつかの利点を持つ別のアプローチを以下で指摘しています。のスーパークラス初期化子ContentHandlerが適切に呼び出された._locator 場合、適切なLocator.
利点: 独自のものを作成する必要はありませんLocator(または作成方法を見つける必要はありません)。欠点: どこにも文書化されておらず、文書化されていないプライベート変数を使用するのは適切ではありません。
ありがとうマルティン!