少し前に、OutSystems 11の特定バージョン間の変更点リストを取得したいことがあった。
Release Notesのページを見れば良いのだが、バージョン間が離れていると、手動でリストを取ってくるのも面倒くさい。
今後のために、簡単なJavaScriptコードのスニペットを用意してみた。
対象
OutSystems 11のPlatform Serverでテスト。
ページ構造は変わる可能性もあるので注意。この記事を書いているのは、2025/06/07。
Release Notesページの構造をチェック
Release Notes > 11 > Platform Serverのタグ構造を確認してみる。
↑はブラウザの開発者ツールでタグ構造を抜粋したもの。
- data属性data-block=WebBlock.InjectHTMLが親タグになっていそう
- 親タグ直下のタグのさらに下に必要なタグが(階層構造を造らずに)平置きされていそう
- バージョン番号がh2タグ内に含まれる
- h2タグの後のh3タグは、該当バージョン内での修正点のカテゴリ(例:Bug Fixing)
- h3タグの後のリスト(ul > liタグ)は該当カテゴリに属する修正点のリストを表す
Release Notesの修正点をJavaScriptオブジェクトに変換するJavaScriptコードスニペット
以上の分析結果をもとに、JavaScriptでHTML情報を抜き出すコードを書けば良いが、利便性のためにいくらか検討が必要。
考慮点
カテゴリがNewの場合
カテゴリがNew(新機能)の場合だけ、カテゴリ名にバージョン番号が入ってしまう。
例:New in Platform Server 11.35.0、New in Platform Server 11.34.1など
カテゴリを抽出した際に、「New」で始まっていたら「New」をカテゴリとして利用すれば良さそう。
カテゴリに揺らぎがある
カテゴリの部分だけを抽出し、重複を排除してJavaScript配列に格納してみると、以下のようになった(Newについては上記対応済み)。
['New', 'Bug Fixing', 'Known issues', 'Breaking change', 'Known Issues', 'Limitation', 'Known issue', 'Breaking Change', 'Breaking changes', 'Breaking Changes']
この結果から、
- 'Known issues', 'Known Issues', 'Known issue' -> 'Known Issues'
- 'Breaking change', 'Breaking Change', 'Breaking changes', 'Breaking Changes' -> 'Breaking Changes'
とカテゴリ名の揺らぎを補正する。
更新内容に含まれる二重引用符の対応
最終的にCSVで出力するので、各項目は二重引用符で囲まれる。
その際に、Release Notes上の更新内容がすでに二重引用符を含んでいると、Excelなどで表示したときに表示が壊れてしまう。
そこで、二重引用符は二重にする("data would be truncated"のような文字列があったら、""data would be truncated""に置換する)。
コードスニペット
// Get the target tags from the document
let targetTags = document.querySelector("[data-block='WebBlock.InjectHMTL']").childNodes[0].children;
const result = [];
let currentVersion = null;
Array.from(targetTags).forEach(node => {
if (node.tagName === "H2") {
if (currentVersion) {
delete currentVersion._currentCategory;
result.push(currentVersion);
}
currentVersion = { VersionNo: node.innerText, categories: {} };
} else if (node.tagName === "H3" && currentVersion) {
currentVersion._currentCategory = node.innerText;
// If the _currentCategory starts with "New", use just "New" as the category name
if (currentVersion._currentCategory.startsWith("New")) {
currentVersion._currentCategory = "New";
}
// ['New', 'Bug Fixing', 'Known issues', 'Breaking change', 'Known Issues', 'Limitation', 'Known issue', 'Breaking Change', 'Breaking changes', 'Breaking Changes'] -> Correct fluctuation ['New', 'Bug Fixing', 'Known Issues', 'Breaking Change', 'Limitation']
if (currentVersion._currentCategory === "Bug Fixing") {
currentVersion._currentCategory = "Bug Fixing";
} else if (currentVersion._currentCategory === "Known issues" || currentVersion._currentCategory === "Known issue") {
currentVersion._currentCategory = "Known Issues";
} else if (currentVersion._currentCategory === "Breaking change" || currentVersion._currentCategory === "Breaking changes" || currentVersion._currentCategory === "Breaking Change") {
currentVersion._currentCategory = "Breaking Changes";
} else if (currentVersion._currentCategory === "Limitation") {
currentVersion._currentCategory = "Limitation";
}
currentVersion.categories[currentVersion._currentCategory] = [];
} else if (node.tagName === "UL" && currentVersion && currentVersion._currentCategory) {
const items = Array.from(node.querySelectorAll("li")).map(li => li.innerText.trim().replace(/"/g, '""')); // replace " with ""
currentVersion.categories[currentVersion._currentCategory].push(...items);
}
});
if (currentVersion) {
delete currentVersion._currentCategory;
result.push(currentVersion);
}
console.log(result);
実行方法
- Release Notesのページ(OutSystems11のPlatform Server) をブラウザで開く
- 開発者ツールを起動
- コンソールを開く
- 上記コードスニペットを貼り付けて実行
- resultという変数にJavaScriptオブジェクトとして格納される
実行結果の例
resultは配列。その各要素は、バージョンを表すオブジェクト。
バージョンオブジェクト
- VersionNo: バージョン番号
- categories: オブジェクト
結果のJavaScriptオブジェクトをCSV文字列に変換するコードスニペット
コードスニペット
上のコードに引き続き以下のコードスニペットを、開発者ツールのコンソールで実行する。
const csvRows = [];
// Add header row
csvRows.push("VersionNo,Category,Update");
// Iterate over each version
result.forEach(version => {
const versionNo = version.VersionNo;
// Iterate over each category in the version
Object.keys(version.categories).forEach(category => {
const updates = version.categories[category];
updates.forEach(update => {
csvRows.push(`"${versionNo}","${category}","${update}"`);
});
});
});
// Join all rows into a single CSV string
const csvString = csvRows.join("\n");
console.log(csvString);