オンライン資格確認で得られるデータ(xml)について

  • オンライン資格確認で、保険証で確認で有効だと、保険情報をダウンロードできる
  • そのファイルはxmlファイルで可読性が低い
  • 以下はpythonを使って、読みやすいようにデータを抽出した記録
  • ダウンロードで得られたファイルを、test-data.xmlとする
  • それをそのまま開くと、
f = open("./test-data.xml","r")
for line in f:
    print(line)
f.close()
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><XmlMsg><MessageHeader><ProcessExecutionTime>20230311082923</ProcessExecutionTime><QualificationConfirmationDate>20230311</QualificationConfirmationDate><MedicalInstitutionCode>1234567890</MedicalInstitutionCode><ReferenceClassification>2</ReferenceClassification><SegmentOfResult>1</SegmentOfResult><CharacterCodeIdentifier>0</CharacterCodeIdentifier></MessageHeader><MessageBody><ProcessingResultStatus>1</ProcessingResultStatus><QualificationValidity>1</QualificationValidity><ResultList><ResultOfQualificationConfirmation><InsuredCardClassification>01</InsuredCardClassification><InsurerNumber>06123456</InsurerNumber><InsuredCardSymbol>123</InsuredCardSymbol><InsuredIdentificationNumber>1027021</InsuredIdentificationNumber><InsuredBranchNumber>00</InsuredBranchNumber><PersonalFamilyClassification>1</PersonalFamilyClassification><Name>山田 太郎</Name><NameKana>ヤマダ タロウ</NameKana><Sex1>1</Sex1><Birthdate>19800101</Birthdate><Address>東京都千代田区麹町1丁目1番地1</Address><PostNumber>102-0083</PostNumber><InsuredCertificateIssuanceDate>20120301</InsuredCertificateIssuanceDate><InsuredCardValidDate>20190401</InsuredCardValidDate><InsurerName>山田健康保険組合</InsurerName><LimitApplicationCertificateRelatedConsFlg>0</LimitApplicationCertificateRelatedConsFlg></ResultOfQualificationConfirmation></ResultList></MessageBody></XmlMsg>
  • jupyter Notebook (6.4.12)において、ライブラリ(xmltodict, openpyxl)のinstall
pip install xmltodict
pip install openpyxl
  • ライブラリのimport
import xmltodict
import json
import pandas as pd
  • xmlを辞書型へ
with open('test-data.xml', encoding='utf-8') as fd:
    doc = xmltodict.parse(fd.read())
  • 辞書型をjson
json_data = json.dumps(doc, indent=2, separators=(',', ':'),ensure_ascii=False)
res = json_data
print(res)
  • データをjson形式表示すると
{
  "XmlMsg":{
    "MessageHeader":{
      "ProcessExecutionTime":"20230311082923",
      "QualificationConfirmationDate":"20230311",
      "MedicalInstitutionCode":"1234567890",
      "ReferenceClassification":"2",
      "SegmentOfResult":"1",
      "CharacterCodeIdentifier":"0"
    },
    "MessageBody":{
      "ProcessingResultStatus":"1",
      "QualificationValidity":"1",
      "ResultList":{
        "ResultOfQualificationConfirmation":{
          "InsuredCardClassification":"01",
          "InsurerNumber":"06123456",
          "InsuredCardSymbol":"123",
          "InsuredIdentificationNumber":"1027021",
          "InsuredBranchNumber":"00",
          "PersonalFamilyClassification":"1",
          "Name":"山田 太郎",
          "NameKana":"ヤマダ タロウ",
          "Sex1":"1",
          "Birthdate":"19800101",
          "Address":"東京都千代田区麹町1丁目1番地1",
          "PostNumber":"102-0083",
          "InsuredCertificateIssuanceDate":"20120301",
          "InsuredCardValidDate":"20190401",
          "InsurerName":"山田健康保険組合",
          "LimitApplicationCertificateRelatedConsFlg":"0"
        }
      }
    }
  }
}
  • 必要なデータは、"XmlMsg"/"MessageBody"/"ResultList"/"ResultOfQualificationConfirmation"にあるようだ。
  • そのデータのみを抽出
data = json.loads(res)
patient_info = data['XmlMsg']['MessageBody']['ResultList']['ResultOfQualificationConfirmation']
df = pd.json_normalize(patient_info)
  • dfの中身は
df
 InsuredCardClassification   InsurerNumber   InsuredCardSymbol   InsuredIdentificationNumber InsuredBranchNumber PersonalFamilyClassification    Name    NameKana    Sex1    Birthdate   Address PostNumber  InsuredCertificateIssuanceDate  InsuredCardValidDate    InsurerName LimitApplicationCertificateRelatedConsFlg
0   01  06123456    123 1027021 00  1   山田 太郎 ヤマダ タロウ  1   19800101    東京都千代田区麹町1丁目1番地1    102-0083    20120301    20190401    山田健康保険組合    0
  • 必要な項目を順番にとりだして、行列を入れ替えると、xmlの呪文が、保険証の記載に近い表記となる
df = df[['PersonalFamilyClassification','InsuredCertificateIssuanceDate','InsuredCardSymbol','InsurerNumber','NameKana','Name','Birthdate','Sex1','InsuredCardValidDate','PostNumber','Address','InsurerNumber','InsurerName']]
df.transpose()
 0
PersonalFamilyClassification    1
InsuredCertificateIssuanceDate  20120301
InsuredCardSymbol   123
InsurerNumber   06123456
NameKana    ヤマダ タロウ
Name    山田 太郎
Birthdate   19800101
Sex1    1
InsuredCardValidDate    20190401
PostNumber  102-0083
Address 東京都千代田区麹町1丁目1番地1
InsurerNumber   06123456
InsurerName 山田健康保険組合
  • ちなみに
  • PersonalFamilyClassification/本人・家族の別, InsuredCertificateIssuanceDate/被保険者証交付年月日,InsuredCardSymbol /被保険者証記号, InsurerNumber/保険者番号,NameKana/氏名カナ,Name/氏名,Birthdate/生年月日,Sex1/性別,InsuredCardValidDate/被保険者証有効開始年月日,PostNumber/郵便番号,Address/住所,InsurerNumber/保険者番号,InsurerName/保険者名称

  • 取り出した情報にエクセル形式で書き出す

df.transpose().to_excel('test-data.xlsx', index=True, header=True)
  • 取り出した情報をCSV形式で書き出し
df.transpose().to_csv('test-data.csv', index=True, header=True)
  • 今回のデータは組合健保を匿名化したもの
  • 保険証の種類は多岐にわたり、形式がかならずしも一致していない
  • 手元のデータの範囲では
  • 郵政省共済、厚生労働省共済、後期高齢には被保険者証記号がない
  • 後期高齢に被保険者証枝番、本人・家族の別がない
  • 上記の共通の項目の他に、前期高齢でElderlyRecipientCertificateInfo.ElderlyRecipientContributionRatio/高齢受給者証一部負担金割合 、後期高齢でInsuredPartialContributionRatio/被保険者証一部負担金割合が必要