xml.dom.minidom —最小限のDOM実装—Pythonドキュメント
xml.dom.minidom —最小限のDOM実装
ソースコード: :source: `Lib / xml / dom / minidom.py`
xml.dom.minidom は、他の言語のAPIと同様のAPIを使用した、ドキュメントオブジェクトモデルインターフェイスの最小限の実装です。 これは、完全なDOMよりも単純で、大幅に小さいことを目的としています。 まだDOMに習熟していないユーザーは、代わりに xml.etree.ElementTree モジュールをXML処理に使用することを検討する必要があります。
警告
xml.dom.minidom モジュールは、悪意を持って構築されたデータに対して安全ではありません。 信頼できないデータまたは認証されていないデータを解析する必要がある場合は、 XMLの脆弱性を参照してください。
DOMアプリケーションは通常、一部のXMLをDOMに解析することから始まります。 xml.dom.minidom では、これは解析関数を介して行われます。
from xml.dom.minidom import parse, parseString
dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name
datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource) # parse an open file
dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
parse()関数は、ファイル名または開いているファイルオブジェクトのいずれかを取ることができます。
- xml.dom.minidom.parse(filename_or_file, parser=None, bufsize=None)
- 指定された入力から
Document
を返します。 filename_or_file は、ファイル名またはファイルのようなオブジェクトのいずれかです。 parser は、指定されている場合、SAX2パーサーオブジェクトである必要があります。 この関数は、パーサーのドキュメントハンドラーを変更し、名前空間のサポートをアクティブにします。 他のパーサー構成(エンティティリゾルバーの設定など)は、事前に行っておく必要があります。
文字列にXMLがある場合は、代わりに parseString()関数を使用できます。
- xml.dom.minidom.parseString(string, parser=None)
- 文字列を表す
Document
を返します。 このメソッドは、文字列の io.StringIO オブジェクトを作成し、それを parse()に渡します。
どちらの関数も、ドキュメントのコンテンツを表すDocument
オブジェクトを返します。
parse()および parseString()関数が行うことは、XMLパーサーを任意のSAXパーサーからの解析イベントを受け入れてDOMツリーに変換できる「DOMビルダー」に接続することです。 。 関数の名前は誤解を招く可能性がありますが、インターフェイスを学習するときに簡単に理解できます。 ドキュメントの解析は、これらの関数が戻る前に完了します。 これらの関数自体がパーサーの実装を提供しないというだけです。
「DOMImplementation」オブジェクトのメソッドを呼び出して、Document
を作成することもできます。 このオブジェクトは、 xml.dom パッケージのgetDOMImplementation()
関数または xml.dom.minidom モジュールを呼び出すことで取得できます。 Document
を入手したら、それに子ノードを追加してDOMにデータを入力できます。
from xml.dom.minidom import getDOMImplementation
impl = getDOMImplementation()
newdoc = impl.createDocument(None, "some_tag", None)
top_element = newdoc.documentElement
text = newdoc.createTextNode('Some textual content.')
top_element.appendChild(text)
DOMドキュメントオブジェクトを取得したら、そのプロパティとメソッドを介してXMLドキュメントの一部にアクセスできます。 これらのプロパティは、DOM仕様で定義されています。 ドキュメントオブジェクトの主なプロパティはdocumentElement
プロパティです。 XMLドキュメントの主要な要素である他のすべてを保持する要素を提供します。 プログラムの例を次に示します。
dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"
DOMツリーが完成したら、オプションでunlink()
メソッドを呼び出して、不要になったオブジェクトの早期クリーンアップを促進できます。 unlink()
は、 xml.dom.minidom 固有のDOMAPIの拡張機能であり、ノードとその子孫を本質的に役に立たないものにします。 それ以外の場合、Pythonのガベージコレクターは最終的にツリー内のオブジェクトを処理します。
DOMオブジェクト
Python用のDOMAPIの定義は、 xml.dom モジュールのドキュメントの一部として提供されています。 このセクションでは、APIと xml.dom.minidom の違いを示します。
- Node.unlink()
DOM内の内部参照を分割して、サイクリックGCのないバージョンのPythonでガベージコレクションされるようにします。 サイクリックGCが使用可能な場合でも、これを使用すると大量のメモリをより早く使用できるようになる可能性があるため、DOMオブジェクトで不要になったらすぐにこれを呼び出すことをお勧めします。 これは、
Document
オブジェクトでのみ呼び出す必要がありますが、子ノードで呼び出すと、そのノードの子を破棄できます。with ステートメントを使用すると、このメソッドを明示的に呼び出すことを回避できます。 次のコードは、
with
ブロックが終了すると、 dom のリンクを自動的に解除します。with xml.dom.minidom.parse(datasource) as dom: ... # Work with dom.
- Node.writexml(writer, indent=, addindent=, newl=, encoding=None, standalone=None)
XMLをライターオブジェクトに書き込みます。 ライターはテキストを受け取りますが、入力としてバイトは受け取りません。ファイルオブジェクトインターフェイスのメソッドと一致する
write()
メソッドが必要です。 indent パラメーターは、現在のノードのインデントです。 addindent パラメーターは、現在のサブノードに使用する増分インデントです。 newl パラメーターは、改行を終了するために使用する文字列を指定します。Document
ノードの場合、追加のキーワード引数 encoding を使用して、XMLヘッダーのエンコードフィールドを指定できます。同様に、 Standalone 引数を明示的に指定すると、スタンドアロンドキュメント宣言がXMLドキュメントのプロローグに追加されます。 値が True に設定されている場合、 Standalone =” yes” が追加され、それ以外の場合は、“ no” に設定されます。 引数を記載しないと、文書から宣言が省略されます。
バージョン3.8で変更: writexml()メソッドは、ユーザーが指定した属性の順序を保持するようになりました。
バージョン3.9で変更: スタンドアロンパラメーターが追加されました。
- Node.toxml(encoding=None, standalone=None)
DOMノードで表されるXMLを含む文字列またはバイト文字列を返します。
明示的な encoding 1 引数を使用すると、結果は指定されたエンコーディングのバイト文字列になります。 encoding 引数がない場合、結果はUnicode文字列になり、結果の文字列のXML宣言はエンコーディングを指定しません。 UTF-8はXMLのデフォルトのエンコーディングであるため、この文字列をUTF-8以外のエンコーディングでエンコードすることはおそらく正しくありません。
スタンドアロン引数は、 writexml()とまったく同じように動作します。
バージョン3.8で変更: toxml()メソッドは、ユーザーが指定した属性の順序を保持するようになりました。
バージョン3.9で変更: スタンドアロンパラメーターが追加されました。
- Node.toprettyxml(indent='\t', newl='\n', encoding=None, standalone=None)
きれいに印刷されたバージョンのドキュメントを返します。 indent はインデント文字列を指定し、デフォルトはタブキーです。 newl は、各行の終わりに出力される文字列を指定し、デフォルトは
\n
です。encoding 引数は、 toxml()の対応する引数のように動作します。
スタンドアロン引数は、 writexml()とまったく同じように動作します。
バージョン3.8で変更: toprettyxml()メソッドは、ユーザーが指定した属性の順序を保持するようになりました。
バージョン3.9で変更: スタンドアロンパラメーターが追加されました。
DOMの例
このサンプルプログラムは、単純なプログラムのかなり現実的な例です。 この特定のケースでは、DOMの柔軟性をあまり活用していません。
import xml.dom.minidom
document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>
<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""
dom = xml.dom.minidom.parseString(document)
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)
def handleSlideshow(slideshow):
print("<html>")
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
print("</html>")
def handleSlides(slides):
for slide in slides:
handleSlide(slide)
def handleSlide(slide):
handleSlideTitle(slide.getElementsByTagName("title")[0])
handlePoints(slide.getElementsByTagName("point"))
def handleSlideshowTitle(title):
print("<title>%s</title>" % getText(title.childNodes))
def handleSlideTitle(title):
print("<h2>%s</h2>" % getText(title.childNodes))
def handlePoints(points):
print("<ul>")
for point in points:
handlePoint(point)
print("</ul>")
def handlePoint(point):
print("<li>%s</li>" % getText(point.childNodes))
def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
print("<p>%s</p>" % getText(title.childNodes))
handleSlideshow(dom)
minidomとDOM標準
xml.dom.minidom モジュールは、基本的にDOM 1.0互換のDOMであり、いくつかのDOM 2機能(主に名前空間機能)を備えています。
PythonでのDOMインターフェースの使用法は簡単です。 次のマッピングルールが適用されます。
- インターフェイスには、インスタンスオブジェクトを介してアクセスします。 アプリケーションはクラス自体をインスタンス化するべきではありません。
Document
オブジェクトで使用可能なクリエーター関数を使用する必要があります。 派生インターフェースは、基本インターフェースからのすべての操作(および属性)に加えて、新しい操作をサポートします。 - 操作はメソッドとして使用されます。 DOMは in パラメーターのみを使用するため、引数は通常の順序(左から右)で渡されます。 オプションの引数はありません。
void
操作はNone
を返します。 - IDL属性はインスタンス属性にマップされます。 PythonのOMGIDL言語マッピングとの互換性のために、属性
foo
はアクセサメソッド_get_foo()
および_set_foo()
を介してアクセスすることもできます。readonly
属性は変更しないでください。 これは実行時に強制されません。 - タイプ
short int
、unsigned int
、unsigned long long
、およびboolean
はすべて、Python整数オブジェクトにマップされます。 - タイプ
DOMString
はPython文字列にマップされます。 xml.dom.minidom はバイトまたは文字列のいずれかをサポートしますが、通常は文字列を生成します。 タイプDOMString
の値は、W3CのDOM仕様によってIDLnull
値を持つことが許可されている場合、None
にすることもできます。 const
宣言は、それぞれのスコープ内の変数にマップされます(例:xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE
); それらは変更してはなりません。DOMException
は現在、 xml.dom.minidom ではサポートされていません。 代わりに、 xml.dom.minidom は、 TypeError や AttributeError などの標準のPython例外を使用します。NodeList
オブジェクトは、Pythonの組み込みリストタイプを使用して実装されます。 これらのオブジェクトは、DOM仕様で定義されたインターフェースを提供しますが、以前のバージョンのPythonでは、公式APIをサポートしていません。 ただし、これらはW3Cの推奨事項で定義されているインターフェイスよりもはるかに「Pythonic」です。
次のインターフェイスは、 xml.dom.minidom に実装されていません。
DOMTimeStamp
EntityReference
これらのほとんどは、ほとんどのDOMユーザーにとって一般的な有用性ではないXMLドキュメント内の情報を反映しています。
脚注
- 1
- XML出力に含まれるエンコーディング名は、適切な標準に準拠している必要があります。 たとえば、「UTF-8」は有効ですが、「UTF8」は、Pythonがエンコード名として受け入れている場合でも、XMLドキュメントの宣言では無効です。 https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDeclおよび https://www.iana.org/assignments/character-setsを参照してください。 /character-sets.xhtml。