はじめに
業務の中で、XMLファイルで作成されているメタデータ一覧の出力が必要になりました。
手でちまちまやるのはあまりにも面倒くさいので、pythonでやってみます。
pythonなんてろくに使ったこともないですが、調べながらなんやかんやで作れました。
良い時代だ。
前提
今回対応したのはSalesforceのメタデータのため、それを取得するコードです。
他パターンでも応用して使えるとは思います。
コード
事前準備
一つだけライブラリを利用するので、インストールする必要があります。
pip install openpyxl
それと当然、pythonのインストールが必要です。
コード
main.py
import os
import xml.etree.ElementTree as ET
import openpyxl
BASE_FOLDER_PATH = 'C:/Users/XXXXX/Documents/Salesforce/SalesforcePackage/force-app/main/default/objects'
TARGET_FOLDER_NAME = 'webLinks'
XMLNS = '{http://soap.sforce.com/2006/04/metadata}'
# 表記の項目を取得する
TARGET_COLUMNS = [
'fullName'
,'masterLabel'
,'displayType'
,'linkType'
,'content'
]
# このリストに含まれている場合、セット処理は作成する必要がある
CUSTOM_COLUMNS = [
'content'
]
# 対象となるフォルダ一覧を取得
directories = [
f for f in os.listdir(BASE_FOLDER_PATH) if os.path.isdir(os.path.join(BASE_FOLDER_PATH, f))
]
objects = {}
# 各オブジェクトフォルダをループ
for objectName in directories:
# 対象となるフォルダパスを組み立てる
targetFolderPath = os.path.join(os.path.join(BASE_FOLDER_PATH, objectName), TARGET_FOLDER_NAME)
# 対象となるフォルダが存在しない場合は飛ばす
if not os.path.isdir(targetFolderPath):
continue
webLinks = {}
# 対象となるフォルダ内のファイル名一覧を取得
files = [
f for f in os.listdir(targetFolderPath) if os.path.isfile(os.path.join(targetFolderPath, f))
]
for fileName in files:
# weblinkファイルを読み込み
tree = ET.parse(os.path.join(targetFolderPath, fileName))
root = tree.getroot()
webLink = {}
for targetColumn in TARGET_COLUMNS:
# 標準のセッター
if targetColumn not in CUSTOM_COLUMNS:
webLink[targetColumn] = root.find(XMLNS + targetColumn).text
# カスタムセッター
if webLink['linkType'] == 'page':
webLink['content'] = root.find(XMLNS + 'page').text
elif webLink['linkType'] == 'url':
webLink['content'] = root.find(XMLNS + 'url').text
else:
webLink['content'] = ''
webLinks[webLink['fullName']] = webLink
objects[objectName] = webLinks
# Excelファイルを開く
wb = openpyxl.Workbook()
ws = wb['Sheet']
# 書き込み処理
row = 1
for objectName, webLinks in objects.items():
for webLink in webLinks.values():
ws.cell(row, 1).value = objectName
col = 2
for columnName in TARGET_COLUMNS:
ws.cell(row, col).value = webLink[columnName]
col = col + 1
row = row + 1
wb.save('C:/Users/XXXXX/Downloads/test.xlsx')
コメントを読むと何となく分かるとは思いますが、コードの流れとしてはこんな感じ。
- 対象フォルダ内にあるフォルダ名一覧を取得
それぞれのオブジェクトフォルダ内にある、webLinks
フォルダ内のファイルが実際に読み取りたいXMLファイルです。 -
webLinks
が存在しないオブジェクトもあるので、存在チェック - 存在していた場合、フォルダ内部の全XMLファイルを読み込んで、必要な情報をdict(連想配列)に保存
- Excelファイルを作成
- Excelファイルに3. で保存した情報を書き出す
- Excelファイルを保存
おわりに
なんかコードが汚い!!!
もうちょっとなんとかしたいけども、今は取りあえず動くし良いでしょう・・。
pythonを使ってみて、気楽にコードを書いて動かすだけなのでお手軽なのですが、記法がなかなかに馴染まないですね。
型も定数宣言もできなかったり、セミコロン不要なのがなんだかソワソワします。