Views: 3
Amazon EC2(Linux)に UN/CEFACT spec-JSONschemaテスト環境構築
2025-06-07
1. Amazon EC2(Linux)に UN/CEFACT spec-JSONschema リポジトリ をクローン
Amazon EC2(Linux)に UN/CEFACT spec-JSONschema リポジトリ をクローンするには、以下の手順で行えます。
✅ 手順:GitHub リポジトリをクローンする(Amazon Linux 2/2023 共通)
1.1. 必要なパッケージのインストール
sudo dnf install -y git # Amazon Linux 2023 の場合
# sudo yum install -y git # Amazon Linux 2 の場合
1.2. 任意の作業ディレクトリに移動(例:ホームディレクトリ)
cd ~
mkdir uncefact && cd uncefact
1.3. リポジトリをクローン
git clone https://github.com/uncefact/spec-JSONschema.git
出力例:
Cloning into 'spec-JSONschema'...
remote: Enumerating objects: ...
remote: Counting objects: ...
...
1.4. 確認
✅ 内容確認
リポジトリには次のような構造のファイルが含まれています:
hema/
├── JSONschema2020-12/
│ ├── library/
│ │ └── BuyShipPay/
│ │ └── D23B/
│ │ └── BasicComponents.json
├── LICENSE
├── README.md
...
✅ 補足(更新・同期)
最新版を取得するにはクローン後に以下を実行:
git pull origin main
2. XBRL GL JSON Schema 対応テスト環境セットアップ手順
📌 目的
2.1. 前提環境の準備(Amazon Linux 2023)
# Node.js と Git のインストール
sudo dnf install -y nodejs git
# 必要であれば tree も
sudo dnf install -y tree
2.2. 作業ディレクトリ作成とAJV環境構築
コマンド
mkdir ~/xbrl-gl-jsonschema && cd ~/xbrl-gl-jsonschema
npm init -y
npm install ajv ajv-formats
実行結果
$ mkdir ~/xbrl-gl-jsonschema && cd ~/xbrl-gl-jsonschema
npm init -y
npm install ajv ajv-formats
Wrote to /home/ec2-user/xbrl-gl-jsonschema/package.json:
{
"name": "xbrl-gl-jsonschema",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
added 6 packages, and audited 7 packages in 2s
2 packages are looking for funding
run npm fund for details
found 0 vulnerabilities
ChatGPT
👍 完了です!
xbrl-gl-jsonschema 環境が正常にセットアップされ、ajv(JSON Schema バリデータ)と ajv-formats(フォーマット拡張)がインストールされました。
3. XBRL GL JSON
インスタンス文書
{
"$schema": "./xbrl-gl-cor-schema.json",
"accountingEntries": [
{
"entryHeader": [
{
"id": {
"content": "Book1"
},
"date": {
"content": "2025-05-12"
},
"description": {
"content": "test book"
},
"entryDetail": [
{
"lineNumber": {
"content": "1"
},
"description": {
"content": "Test entry"
},
"debitAmount": {
"content": "1000",
"currencyId": "JPY"
},
"creditAmount": {
"content": "1000",
"currencyId": "JPY"
},
"accountCode": {
"content": "JSD0010"
}
}
]
}
]
}
]
}
スキーマ定義
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://xbrl.org/XBRL-GL-YYYY-MM-DD/schemas/gl-cor.json",
"title": "XBRL GL Core Module Schema (Garden of Eden)",
"description": "Fully modular schema where all definitions and properties are declared globally and referenced.",
"type": "object",
"properties": {
"accountingEntries": {
"$ref": "#/$defs/AccountingEntries"
}
},
"required": [
"accountingEntries"
],
"$defs": {
"AccountingEntries": {
"type": "array",
"items": {
"$ref": "#/$defs/AccountingEntry"
}
},
"AccountingEntry": {
"type": "object",
"properties": {
"entryHeader": {
"$ref": "#/$defs/EntryHeaders"
}
},
"required": [
"entryHeader"
]
},
"EntryHeaders": {
"type": "array",
"items": {
"$ref": "#/$defs/EntryHeader"
}
},
"EntryHeader": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/ID"
},
"date": {
"$ref": "#/$defs/Date"
},
"description": {
"$ref": "#/$defs/Description"
},
"entryDetail": {
"$ref": "#/$defs/EntryDetails"
}
},
"required": [
"id",
"date"
]
},
"EntryDetails": {
"type": "array",
"items": {
"$ref": "#/$defs/EntryDetail"
}
},
"EntryDetail": {
"type": "object",
"properties": {
"lineNumber": {
"$ref": "#/$defs/LineNumber"
},
"accountCode": {
"$ref": "#/$defs/AccountCode"
},
"debitAmount": {
"$ref": "#/$defs/DebitAmount"
},
"creditAmount": {
"$ref": "#/$defs/CreditAmount"
},
"description": {
"$ref": "#/$defs/Description"
}
},
"required": [
"lineNumber",
"accountCode"
]
},
"ID": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/idType"
},
"Date": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/dateType"
},
"Description": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/textType"
},
"LineNumber": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/numericType"
},
"AccountCode": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/codeType"
},
"DebitAmount": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/amountType"
},
"CreditAmount": {
"$ref": "D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/amountType"
}
}
}
スキーマ定義では、UN/CEFACTが提供するUDT(Unqualified Data Type)定義を参照しています。
ChatGPT
✅ 今の構成概要
xbrl-gl-instance.json はインスタンス(データ)
xbrl-gl-cor-schema.json(誤:xbrl-gl-cor.json)は JSON Schema 本体
$defs を中心にモジュール定義している
各基本型(idType, amountType など)は UNECE-BasicComponents.json から $ref している(D23B/)
3.1. ディレクトリ構造を準備
mkdir -p schemas/D23B
mv xbrl-gl-cor.json schemas/xbrl-gl-cor-schema.json
mv xbrl-gl-instance.json instance.json
次に UNECE BasicComponents.json を取得:
curl -o schemas/D23B/UNECE-BasicComponents.json \
https://raw.githubusercontent.com/uncefact/spec-JSONschema/main/JSONschema2020-12/library/BuyShipPay/D23B/UNECE-BasicComponents.json
3.2. 検証スクリプト validate.js を作成
const Ajv2020 = require("ajv/dist/2020").default;
const addFormats = require("ajv-formats");
const fs = require("fs");
const path = require("path");
// AJVインスタンス作成
const ajv = new Ajv2020({
strict: false,
loadSchema: async (uri) => {
const filePath = path.resolve("schemas", uri.replace(/^.*\/D23B\//, "D23B/"));
return JSON.parse(fs.readFileSync(filePath));
}
});
addFormats(ajv);
// スキーマとデータの読み込み
(async () => {
const schema = JSON.parse(fs.readFileSync("schemas/xbrl-gl-cor-schema.json"));
const data = JSON.parse(fs.readFileSync("instance.json"));
// 外部参照を含むスキーマを非同期にcompile
const validate = await ajv.compileAsync(schema);
const valid = validate(data);
if (valid) {
console.log("✅ Valid!");
} else {
console.error("❌ Validation errors:", validate.errors);
}
})();
3.3. 実行
node validate.js
✅ 注意点
$ref のパス “D23B/UNECE-BasicComponents.json#…” は ローカル相対パスになるため、validate.js で loadSchema() を使って手動解決が必要。
Ajv.compileAsync() は $ref 解決のために必須。
JSON Schema の $schema は “https://json-schema.org/draft/2020-12/schema” にするとさらに将来的に整合性が良いです(今は draft-07 になっている)。
3.4. 現状のディレクトリ構成
$ tree -L 3
.
├── jsonschema-dev
│ ├── node_modules
│ │ ├── ajv
│ │ ├── ajv-formats
│ │ ├── fast-deep-equal
│ │ ├── fast-uri
│ │ ├── json-schema-traverse
│ │ └── require-from-string
│ ├── package-lock.json
│ ├── package.json
│ └── validate.js
├── uncefact
│ └── spec-JSONschema
│ ├── CODEOWNERS
│ ├── JSONschema2020-12
│ ├── README.md
│ ├── compatibility
│ ├── examples
│ └── images
└── xbrl-gl-jsonschema
├── node_modules
│ ├── ajv
│ ├── ajv-formats
│ ├── fast-deep-equal
│ ├── fast-uri
│ ├── json-schema-traverse
│ └── require-from-string
├── package-lock.json
└── package.json
22 directories, 7 files
ChatGPT
ありがとうございます。現在のディレクトリ構成を見る限り、uncefact/spec-JSONschema/JSONschema2020-12/library/BuyShipPay/D23B/UNECE-BasicComponents.json を XBRL GL用 JSON Schema の $ref で参照する準備は整っています。
✅ 次のステップ:xbrl-gl-cor-schema.json と xbrl-gl-instance.json を追加
まず、XBRL GL 用スキーマとインスタンスファイルを配置します:
mkdir -p ~/xbrl-gl-jsonschema/schemas
mkdir -p ~/xbrl-gl-jsonschema/samples
🔹 xbrl-gl-cor-schema.json を作成(schemas 配下)
nano ~/xbrl-gl-jsonschema/schemas/xbrl-gl-cor-schema.json
その中で UNECE-BasicComponents.json を以下のように相対参照:
"DebitAmount": {
"$ref": "../../uncefact/spec-JSONschema/JSONschema2020-12/library/BuyShipPay/D23B/UNECE-BasicComponents.json#/$defs/udt/$defs/amountType"
}
必要なすべての $ref をこのパターンにします。
🔹 xbrl-gl-instance.json を作成(samples 配下)
✅ 検証スクリプトの配置と実行
🔹 validate.js の作成(ルートディレクトリ)
const Ajv = require("ajv/dist/2020").default;
const addFormats = require("ajv-formats");
const fs = require("fs").promises;
const path = require("path");
const ajv = new Ajv({
strict: false,
loadSchema: async (uri) => {
const base = path.resolve(__dirname, "uncefact/spec-JSONschema/JSONschema2020-12/library/BuyShipPay/D23B");
if (uri.includes("UNECE-BasicComponents.json")) {
const fullPath = path.join(base, "UNECE-BasicComponents.json");
return JSON.parse(await fs.readFile(fullPath, "utf8"));
}
throw new Error(`Unknown schema URI: ${uri}`);
}
});
addFormats(ajv);
(async () => {
const schema = JSON.parse(await fs.readFile("schemas/xbrl-gl-cor-schema.json", "utf8"));
const data = JSON.parse(await fs.readFile("samples/xbrl-gl-instance.json", "utf8"));
const validate = await ajv.compileAsync(schema);
const valid = validate(data);
if (valid) {
console.log("✅ Valid!");
} else {
console.error("❌ Validation errors:");
console.error(validate.errors);
}
})();
✅ 実行
cd ~/xbrl-gl-jsonschema
node validate.js
✅ 結果例
成功 → ✅ Valid!
エラー → エラー内容が validate.errors に出力されます(パスや $ref の指定ミスも含め)
onst fs = require("fs").promises;
const path = require("path");
const Ajv2020 = require("ajv/dist/2020");
const addFormats = require("ajv-formats");
async function loadSchema(uri) {
const base = path.resolve(__dirname, "schemas");
// Draft 2020-12 メインスキーマ
if (uri === "http://json-schema.org/draft/2020-12/schema") {
const fullPath = path.join(base, "draft2020-12.json");
const schema = JSON.parse(await fs.readFile(fullPath, "utf8"));
delete schema["$id"];
return schema;
}
// 各 vocabulary メタスキーマ
const vocabularies = [
"core",
"applicator",
"unevaluated",
"validation",
"meta-data",
"format-annotation",
"content"
];
for (const name of vocabularies) {
if (uri === `http://json-schema.org/draft/2020-12/meta/${name}`) {
const fullPath = path.join(base, "meta", `${name}.json`);
const schema = JSON.parse(await fs.readFile(fullPath, "utf8"));
delete schema["$id"];
return schema;
}
}
// その他カスタムスキーマ
if (uri.includes("UNECE-BasicComponents.json")) {
const fullPath = path.join(
__dirname,
"../uncefact/spec-JSONschema/JSONschema2020-12/library/BuyShipPay/D23B/UNECE-BasicComponents.json"
);
return JSON.parse(await fs.readFile(fullPath, "utf8"));
}
if (uri.includes("codelists/")) {
const fileName = path.basename(uri);
const fullPath = path.join(
__dirname,
"../uncefact/spec-JSONschema/JSONschema2020-12/library/BuyShipPay/D23B/codelists",
fileName
);
return JSON.parse(await fs.readFile(fullPath, "utf8"));
}
throw new Error(`Unknown schema URI: ${uri}`);
}
const ajv = new Ajv2020({
loadSchema,
strict: false
});
addFormats(ajv);
(async () => {
try {
const schemaPath = path.join(__dirname, "schemas/xbrl-gl-cor-schema.json");
const instancePath = path.join(__dirname, "samples/xbrl-gl-instance.json");
const schema = JSON.parse(await fs.readFile(schemaPath, "utf8"));
const data = JSON.parse(await fs.readFile(instancePath, "utf8"));
const validate = await ajv.compileAsync(schema);
const valid = validate(data);
if (valid) {
console.log(" Validation successful: data is valid against the schema.");
} else {
console.error(" Validation errors:");
console.error(validate.errors);
}
} catch (err) {
console.error(" Runtime error:", err);
}
})();
コメントを残す