Peppol BIS Billing JP 0.9定義の確認ページを公開

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()


投稿日

カテゴリー:

, ,

投稿者:

タグ: