[[ノート>ノート/ノート]] [[前のページ>ノート/Pythonその4]]~ 訪問者数 &counter(); 最終更新 &lastmod(); **2009/02/09 PythonとXML [#s1b8b47d] ***参考資料 [#kbe1682a] -[[13.5 xml.parsers.expat -- Expat を使った高速な XML 解析:http://www.python.jp/doc/2.4/lib/module-xml.parsers.expat.html]] -[[The Expat XML Parser:http://www.libexpat.org/]] -[[Using Expat by Clark Cooper September 01, 1999:http://www.xml.com/pub/a/1999/09/expat/index.html]] ***Expat (C言語用。copied from [[Using Expat by Clark Cooper September 01, 1999:http://www.xml.com/pub/a/1999/09/expat/index.html]]) [#x8eb6cb5] -Expatはstream-orientedのパーサーで、このパーサーにコールバック(ハンドラ)関数を登録しておいて文書を食わせ始めればよい。パーサーが文書を解釈できると、その部分に対応するハンドラを呼ぶ。 文書を部分に分けて食わせてよいので、文書全体が確定する前にパーサーを始める事ができるし、メモリに入らないぐらい大きな文書をパーズすることもできる。 -Expatはハンドラやオプションがたくさんあるのでとっつきにくい感もあるが、下の4つの関数を分かれば、普通やりたいことの 80% はできる。 --XML_ParserCreate 新しいパーサーを生成する --XML_SetElementHandler 開始と終了のタグに対してハンドラをセットする --XML_SetCharacterDataHandler テキストにハンドラをセットする --XML_Parse パーサーにテキストの入ったバッファを渡す -C Example (元々C言語用だからこの資料にはCで書いてある。Python用は別途) /***************************************************************** * outline.c * * Copyright 1999, Clark Cooper * All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the same terms as Perl. * * Read an XML document from standard input and print an element * outline on standard output. */ #include <stdio.h> #include "xmlparse.h" #define BUFFSIZE 8192 char Buff[BUFFSIZE]; int Depth; void start(void *data, const char *el, const char **attr) { int i; for (i = 0; i < Depth; i++) printf(" "); printf("%s", el); for (i = 0; attr[i]; i += 2) { printf(" %s='%s'", attr[i], attr[i + 1]); } printf("\n"); Depth++; } /* End of start handler */ void end(void *data, const char *el) { Depth--; } /* End of end handler */ void main(int argc, char **argv) { XML_Parser p = XML_ParserCreate(NULL); if (! p) { fprintf(stderr, "Couldn't allocate memory for parser\n"); exit(-1); } XML_SetElementHandler(p, start, end); for (;;) { int done; int len; len = fread(Buff, 1, BUFFSIZE, stdin); if (ferror(stdin)) { fprintf(stderr, "Read error\n"); exit(-1); } done = feof(stdin); if (! XML_Parse(p, Buff, len, done)) { fprintf(stderr, "Parse error at line %d:\n%s\n", XML_GetCurrentLineNumber(p), XML_ErrorString(XML_GetErrorCode(p))); exit(-1); } if (done) break; } } /* End of main */ ***2009/02/09 Expat in Python (copied from [[13.5.3 例:http://www.python.jp/doc/2.4/lib/expat-example.html]]) [#a99c480f]L [#b60f0b0d] import xml.parsers.expat # 3 handler functions def start_element(name, attrs): print 'Start element:', name, attrs def end_element(name): print 'End element:', name def char_data(data): print 'Character data:', repr(data) p = xml.parsers.expat.ParserCreate() p.StartElementHandler = start_element p.EndElementHandler = end_element p.CharacterDataHandler = char_data p.Parse("""<?xml version="1.0"?> <parent id="top"><child1 name="paul">Text goes here</child1> <child2 name="fred">More text</child2> </parent>""") ***2010/05/09 Expat in Pythonに追加。特にUTF-8漢字を含めて。 [#m303e38b] http://d.hatena.ne.jp/kakurasan/20080603/p1 より #! /usr/bin/python # -*- encoding: utf-8 -*- from xml.parsers.expat import ParserCreate import sys def start_element(name, attrs): print u"要素の開始: %s".encode("utf-8") % name.encode("utf-8") for (key, val) in attrs.iteritems(): # 辞書の各キーに対する処理を行う print u" 属性: %s = %s".encode("utf-8") % (key.encode("utf-8"), val.encode("utf-8")) def end_element(name): print u"要素の終了: %s".encode("utf-8") % name.encode("utf-8") def char_data(data): if data != "\n": print u" 文字データ: %s".encode("utf-8") % data.encode("utf-8") p = ParserCreate() p.buffer_text = True # 文字データが細切れにならないように # ハンドラ関数の関連付け p.StartElementHandler = start_element # 要素の開始 p.EndElementHandler = end_element # 要素の終了 p.CharacterDataHandler = char_data # 文字データ if len(sys.argv) < 2: print >> sys.stderr, u"エラー: 入力ファイルが指定されていません".encode("utf-8") sys.exit(1) infile = sys.argv[1] try: f = open(infile) except IOError: print >> sys.stderr, u'エラー: ファイル "%s" が開けませんでした'.encode("utf-8") % infile sys.exit(1) p.ParseFile(f) # 処理を実行 ***2009/05/09 XMLにおける名前空間 [#jb936266] bingアクセス時に出てきた。~ 知識として -[[XMLにおける名前空間:http://www.mlab.im.dendai.ac.jp/~yamada/web/xml/namespace.html]] -MSのページから [[XML:http://msdn.microsoft.com/ja-jp/data/bb190600.aspx]] **メモ Python+MySQLで漢字(utf-8)を格納したいとき [#o0880b05] はじめに、Python+MySQLをFedoraで入れるには yum install MySQL-python が必要だった。 -python --pythonのデフォルトエンコーディングをutf8にしておくこと。 ## To run with Kanji properly, the Python default encoding should be set to utf-8. ## This is done by including the file /usr/lib/python2.5/site-packages/sitecustomize.py ## with such lines as ## #!/usr/bin/env python ## import sys ## sys.setdefaultencoding('utf-8') ## To check this is properly set, start python and issue ## import sys ## sys.getdefaultencoding() ## which should reply with utf-8. ## See http://python.matrix.jp/tips/string/encoding.html や ### A magic for printing UTF-8 characters sys.stdout = codecs.getwriter('utf_8')(sys.stdout) また、MySQLをConnectするときに connect = MySQLdb.connect(db="dbname", host="localhost", port=3306, user="whoever", passwd="whatever",charset="utf8") のようにcharsetを"utf8"と指定すること。[[Python MySQL 文字コードの指定:http://fujishinko.exblog.jp/6790120/]] -MySQL側もデフォルトがutf8になっていること。~ /etc/my.cnf の設定ファイルを変更。以下の項目を[mysqld]に追加。 default-character-set=utf8 character-set-server=utf8 これにて、mysqldをリスタート。~ 確認はmysql環境で mysql> show variables like "char%"; で +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ になった。[[MySQLの文字コードをUTF8に設定したい:http://it.kndb.jp/entry/show/id/15]] *** [#f844a07f]