PythonがXMLフォーマットデータを処理する方法の詳細

7131 ワード

この例では、PythonがXML形式のデータを処理する方法について説明します.皆さんの参考にしてください.具体的には以下の通りです.
ここでの操作はPython 3プラットフォームに基づいています.
Pythonを用いてXMLを処理する問題では,まず符号化の問題に遭遇する.
Pythonはgb 2312をサポートしていないため、encoding=「gb 2312」のXMLファイルにエラーが発生します.Pythonが読み込んだファイル自体の符号化によって放出異常が生じる場合もありますが、その場合はファイルを開くときに符号化を指定する必要があります.また、XMLのノードに含まれる中国語です.
私のところは、処理が簡単で、XMLのencodingヘッダを修正するだけです.

#!/usr/bin/env python
import os, sys
import re
def replaceXmlEncoding(filepath, oldEncoding='gb2312', newEncoding='utf-8'):
  f = open(filepath, mode='r')
  content = f.read()
  content = re.sub(oldEncoding, newEncoding, content)
  f.close()
  f = open(filepath, mode='w')
  f.write(content)
  f.close()
if __name__ == "__main__":
  replaceXmlEncoding('./ActivateAccount.xml')


次にxmlを用いる.etree.ElementTreeはXMLファイルを操作します.
クラス内で定義_call__関数は、次のコードの最後の行など、クラスを呼び出すことができます.main__で行ないます.これもPythonの世界で際立っていて、すべてが対象で、対象自体を含めて:)
ずっと感じてたmain__関数をテストするのは本当に使いやすいです.

#!/usr/bin/env python
import os, re
import xml.etree.ElementTree as etree
Locale_Path = "./locale.txt"
class xmlExtractor(object):
  def __init__(self):
    pass
  def __call__(self, filepath):
    retDict = {}
    f = open(filepath, 'r')
    Line = len(open(filepath, 'r').readlines())
    retDict['Line'] = Line
    tree = etree.parse(f)
    root = tree.find("ResItem")
    Id = root.get("ID")
    retDict['Title'] = Id
    resItemCnt = len(list(root.findall("ResItem"))) + 1
    retDict['ResItemCount'] = resItemCnt
    retDict['ChineseTip'] = 'None'
    for child in root:
      attrDict = child.attrib
      keyword = "Name"
      if(keyword in attrDict.keys() and attrDict['Name'] == "Caption"):
        if len(child.attrib['Value']) > 1:
          if child.attrib['Value'][0] == '~':
            title = child.attrib['Value'][1:]
          else:
            title = child.attrib['Value'][0:]
          #print(title)
          chs = open(Locale_Path).read()
          pattern = '[^>]+>'
          m = re.search(pattern, chs)
          if m != None:
            realTitle = re.sub(']+>', '', m.group(0))
            retDict['ChineseTip'] = realTitle
    f.close()
    return retDict
if __name__ == "__main__":
  fo = xmlExtractor()
  d = fo('./ActivateAccount.xml')
  print(d)


最後に、エントリファイルで、上の2つのファイルをインポートし、xmlを使用します.domとos.Listdirは、XMLファイルを再帰的に処理し、結果セットを生成します.
ずっとPythonのUnboundLocalErrorエラーが面白いと思っていたので、シンボルテーブルの上書き問題かどうか分かりません.

#!/usr/bin/env python
from xmlExtractor import *
from replaceXmlEncoding import *
from xml.dom import minidom,Node
doc = minidom.Document()
extractor = xmlExtractor()
totalLines = 0
totalResItemCnt = 0
totalXmlFileCnt = 0
totalErrorCnt = 0
errorFileList = []
xmlRoot = doc.createElement("XmlResourceFile")
doc.appendChild(xmlRoot)
def myWalkDir(level, path):
  global doc, extractor, totalLines, totalResItemCnt, totalXmlFileCnt
  global totalErrorCnt, errorFileList
  global xmlRoot
  for i in os.listdir(path):
    if i[-3:] == 'xml':
      totalXmlFileCnt += 1
      try:
        #  xml encoding gb2312   utf-8
        replaceXmlEncoding(path + '\\' + i)
        #   xml        
        info = extractor(path + '\\' + i)
        #                      
        #print(info)
        #print(type(i))
        xmlNode = doc.createElement("XmlFile")
        xmlRoot.appendChild(xmlNode)
        xmlName = doc.createElement("Filename")
        xmlName.setAttribute('Value', i)
        #xmlName.appendChild(doc.createTextNode(i))
        xmlNode.appendChild(xmlName)
        filePath = doc.createElement("Filepath")
        filePath.setAttribute('Value', path[34:])
        #filePath.appendChild(doc.createTextNode(path[1:]))
        xmlNode.appendChild(filePath)
        titleNode = doc.createElement("Title")
        titleNode.setAttribute('Value', str(info['Title']))
        #titleNode.appendChild(doc.createTextNode(str(info['Title'])))
        xmlNode.appendChild(titleNode)
        chsNode = doc.createElement("ChineseTip")
        chsNode.setAttribute('Value', str(info['ChineseTip']))
        #chsNode.appendChild(doc.createTextNode(str(info['Chinese'])))
        xmlNode.appendChild(chsNode)
        resItemNode = doc.createElement("ResItemCount")
        resItemNode.setAttribute('Value', str(info['ResItemCount']))
        #resItemNode.appendChild(doc.createTextNode(str(info['ResItemCount'])))
        xmlNode.appendChild(resItemNode)
        lineNode = doc.createElement("LineCount")
        lineNode.setAttribute('Value', str(info['Line']))
        #lineNode.appendChild(doc.createTextNode(str(info['Line'])))
        xmlNode.appendChild(lineNode)
        descNode = doc.createElement("Description")
        descNode.setAttribute('Value', '')
        #descNode.appendChild(doc.createTextNode(''))
        xmlNode.appendChild(descNode)
      except Exception as errorDetail:
        totalErrorCnt += 1
        errorFileList.append(path + '\\' + i)
        print(path + '\\' + i, errorDetail)
    if os.path.isdir(path + '\\' + i):
      myWalkDir(level+1, path + '\\' + i)
if __name__ == "__main__":
  path = os.getcwd() + '\\themes'
  myWalkDir(0, path)
  print(totalXmlFileCnt, totalErrorCnt)
  #print(doc.toprettyxml(indent = "  "))
  resultXml = open("./xmlResourceList.xml", "w")
  resultXml.write(doc.toprettyxml(indent = "  "))
  resultXml.close()


PS:ここではxml操作に関するオンラインツールをいくつか提供します.
オンラインXML/JSON相互変換ツール:http://tools.jb51.net/code/xmljson
オンラインフォーマットXML/オンライン圧縮XML:http://tools.jb51.net/code/xmlformat
XMLオンライン圧縮/フォーマットツール:http://tools.jb51.net/code/xml_format_compress
XMLコードオンラインフォーマット美化ツール:http://tools.jb51.net/code/xmlcodeformat
Pythonに関する詳細については、「Python操作xmlデータテクニックまとめ」、「Pythonデータ構造とアルゴリズムチュートリアル」、「Python Socketプログラミングテクニックまとめ」、「Python関数使用テクニックまとめ」、「Python文字列操作テクニックまとめ」、『Python入門と進級経典教程』及び『Pythonファイルとディレクトリ操作技術要約』
ここではPythonプログラムの設計に役立つことを願っています.