Views: 38
JP 0.9定義の確認ページを公開
JP V0.9に基づいてOpen Peppolの電子インボイスの定義内容を表示するサイトを作成しました。
公式ページからダウンロード出来るスキーマトロンファイルには、BASICルールが含まれていません。そのため、python のライブラリを使って、ページの内容からデータを抽出してみました。ルールは、本家からページ内容をBeautiful Soupで読み出して加工していますので、誤っている箇所もあるかもしれません。
BASICルールは、未だ確認中のようで、次の様なものも含まれています。
UBLのCardinality定義が0..1なので、複数あるとスキーマ検証でエラーとなり、2つ以上定義出来ません。
次の定義は、BasicとSharedで同じ条件に対して違う表現を使用しており、あえてSharedのルールを定義しなくても良いと思います。
おまけ
Pytho3(Beautiful Soup)のプログラムは、下記です。
response = request.urlopen(base_url)
soup = BeautifulSoup(response,”lxml”)
response.close()
の3行でbase_urlで指定したページを読み込んでJSONファイルに保存しています。
#!/usr/bin/env python3 # # generate CSV from Open Peoopl e-Invoice (UBL 2.1) # # designed by SAMBUICHI, Nobuyuki (Sambuichi Professional Engineers Office) # written by SAMBUICHI, Nobuyuki (Sambuichi Professional Engineers Office) # # MIT License # # Copyright (c) 2021 SAMBUICHI Nobuyuki (Sambuichi Professional Engineers Office) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from bs4 import BeautifulSoup from urllib import request import urllib import os import sys import json import ssl ssl._create_default_https_context = ssl._create_unverified_context root_rule_url = 'https://test-docs.peppol.eu/japan/master/billing-1.0/invoice-1.0/rule/' basic_rule_url = 'https://test-docs.peppol.eu/japan/master/billing-1.0/invoice-1.0/rule/basic/' shared_rule_url = 'https://test-docs.peppol.eu/japan/master/billing-1.0/invoice-1.0/rule/PINT-UBL-validation-preprocessed/' aligned_rule_url = 'https://test-docs.peppol.eu/japan/master/billing-1.0/invoice-1.0/rule/Japan-UBL-validation-preprocessed/' def parse_rule(base_url,RULE): try: response = request.urlopen(base_url) soup = BeautifulSoup(response,"lxml") response.close() tr_s = soup.find_all('tr') header = [x.text for x in tr_s[0].find_all('th')] rules = [] for i in range(len(tr_s)-1): data = [x.text for x in tr_s[i+1].find_all('td')] rules.append(data) results = [] for rule in rules: id = rule[0] message = rule[1] rule_url = f'{root_rule_url}{id}/' response = request.urlopen(rule_url) soup = BeautifulSoup(response,"lxml") response.close() dl = soup.find('dl') title = [x.text for x in dl.find_all('dt')] value = [x for x in dl.find_all('dd')] data = {} data[header[0]] = id data[header[1]] = message for i in range(len(title)): data[title[i]] = value[i].text results.append(data) dir = os.path.dirname(__file__) out_file = os.path.join(dir, f'Rules_{RULE}.json') with open(out_file, 'w') as f: json.dump(results, f, indent=4) except urllib.error.HTTPError as err: print("WARN", err.code, base_url, file=sys.stderr) return False except urllib.error.URLError as err: print("ERROR", err.reason, base_url, file=sys.stderr) return False print("DONE BeautifulSoup", base_url) def main(): parse_rule(basic_rule_url,'Basic') parse_rule(shared_rule_url,'Shared') parse_rule(aligned_rule_url,'Aligned') if __name__ == '__main__': main()