2013-02-28 11 views
8

SVGファイルは基本的にXMLファイルなので、文字列<?xml(または16進表現:'3c 3f 78 6d 6c')を魔法の数字として使用できますが、余分な空白がある場合このチェックを破る可能性があります。マジックナンバーを使用せずにファイルをSVGとするにはどうすればいいですか?

確認が必要な画像は、すべてバイナリであり、魔法の数字があります。最終的にPythonを使用して拡張子を使用せずにファイルがSVG形式であるかどうかを速やかに確認するにはどうすればよいですか?

+0

バイナリとしてファイルの先頭を読み取る方法 - マジックナンバーが見つからない場合は、それをテキストとして読み取り、それを既知のテキストパターンに一致させようとしますか? – dmg

+0

@DJV合理的に聞こえる。そして、私はそれがどのように壊れないのか分からない。 –

答えて

10

XMLは<?xmlプリアンブルで始める必要はありません。そのため、その接頭辞をテストするのは良い検出手法ではありません。すべてのXMLがSVGであるとは言えません。まともな検出、および実装が本当に簡単、ファイルがsvgトップレベルの要素が含まれている整形式のXMLであることをテストするために、実際のXMLパーサーを使用することです:

import xml.etree.cElementTree as et 

def is_svg(filename): 
    tag = None 
    with open(filename, "r") as f: 
     try: 
      for event, el in et.iterparse(f, ('start',)): 
       tag = el.tag 
       break 
     except et.ParseError: 
      pass 
    return tag == '{http://www.w3.org/2000/svg}svg' 

cElementTreeを使用して、検出であることを保証しますexpatの使用によって効率的です。 timeitは、SVGファイルが〜200μsで検出され、非SVGが35μsで検出されたことを示します。 iterparse APIを使用すると、パーサーは合計ファイルサイズに関係なく、要素ツリー全体(モジュール名にかかわらず)を作成せずに、ドキュメントの最初の部分だけを読み込むことができます。

+1

質問を読むことによって、バイナリマジックナンバーとXMLが混在すると赤い警告が表示されました。この回答は、バイナリ形式の解析には1つのアプローチが必要であり、(テキストベースの)XMLの読み取りには完全に異なるアプローチが必要であることが明らかです。 – heltonbiker

+2

@heltonbiker正確に。マジックナンバーには、生のパフォーマンスというものがあります。これは、提案されたアプローチの*効率的な実装を示すコードサンプルが回答に含まれている理由です。 – user4815162342

+0

また、私が正しく理解していれば、プレーンテキストファイルのように、バイナリファイルは本質的に構造化されていません。プレーンテキストでは、シバンやドタイプなどを含めるべきですが、バイナリにはそのような簡潔で謎のマジックナンバーが必要です。その意味では、このマジックナンバーは、データをファイルに格納するための最小サイズで可能な低レベルの「古い方法」を思い起こさせるものですが、XMLやJSONは、データをファイルに格納するための、読み込み不能な膨大な冗長な方法です。両方のアプローチは、1つ以上の側面で異なる。 – heltonbiker

2

ファイルの先頭をバイナリとして読むことができます。マジックナンバーが見つからない場合は、それをテキストファイルとして読み取り、任意のテキストパターンに一致させます。またはその逆。

関連する問題