Parse and serialize HomeBank XHB files.
Parse an XHB string and inspect its contents
Parse an XHB string and inspect its contents
import { assertEquals } from "@std/assert"; import { parse } from "@hertzg/xhb"; // deno-fmt-ignore const xml = [ '<?xml version="1.0"?>', '<homebank v="1.3" d="050204">', '<cur key="1" flags="0" iso="GBP" name="Pound Sterling" symb="£" syprf="1" dchar="." gchar="," frac="2" rate="0" mdate="0"/>', '<account key="1" pos="1" type="1" curr="1" name="Cheque Account" number="01548726554" bankname="Amiga Universal Bank" initial="76.219999999999999" minimum="-30.489999999999998" cheque1="8760951"/>', '<pay key="1" name="Amazon"/>', '<cat key="1" flags="1" name="Food"/>', '<tag key="1" name="groceries"/>', '<ope date="736968" amount="-42.5" account="1" paymode="1" payee="1" category="1" wording="Weekly shop" tags="groceries"/>', '</homebank>', '', ].join("\n"); const xhb = parse(xml); assertEquals(xhb.versions.file, "1.3"); assertEquals(xhb.currencies.length, 1); assertEquals(xhb.currencies[0].isoCode, "GBP"); assertEquals(xhb.accounts.length, 1); assertEquals(xhb.accounts[0].name, "Cheque Account"); assertEquals(xhb.payees.length, 1); assertEquals(xhb.payees[0].name, "Amazon"); assertEquals(xhb.operations.length, 1); assertEquals(xhb.operations[0].amount, "-42.5"); assertEquals(xhb.operations[0].memo, "Weekly shop"); assertEquals(xhb.operations[0].tags, ["groceries"]);
Round-trip: parse then serialize produces identical output
Round-trip: parse then serialize produces identical output
import { assertEquals } from "@std/assert"; import { parse, serialize } from "@hertzg/xhb"; // deno-fmt-ignore const xml = [ '<?xml version="1.0"?>', '<homebank v="1.3" d="050204">', '<cur key="1" flags="0" iso="GBP" name="Pound Sterling" symb="£" syprf="1" dchar="." gchar="," frac="2" rate="0" mdate="0"/>', '<account key="1" pos="1" type="1" curr="1" name="Cheque Account" number="01548726554" bankname="Amiga Universal Bank" initial="76.219999999999999" minimum="-30.489999999999998" cheque1="8760951"/>', '</homebank>', '', ].join("\n"); const xhb = parse(xml); const output = serialize(xhb); assertEquals(output, xml);
Modify a parsed XHB and serialize it back
Modify a parsed XHB and serialize it back
import { assertEquals } from "@std/assert"; import { parse, serialize } from "@hertzg/xhb"; // deno-fmt-ignore const xml = [ '<?xml version="1.0"?>', '<homebank v="1.3" d="050204">', '<pay key="1" name="Amazon"/>', '</homebank>', '', ].join("\n"); const xhb = parse(xml); xhb.payees.push({ key: 2, name: "Grocery Store", payMode: 0, category: 0 }); const output = serialize(xhb); assertEquals(output.includes('name="Grocery Store"'), true); assertEquals(xhb.payees.length, 2);
Parses an XHB XML string into a typed XHB object.
Serializes an XHB object back into an XHB XML string.
A bank account from the <account> element.
-
bankName: gCharP
Name of the bank.
-
bankNumber: gCharP
Bank account number.
-
chequeBookNumber1: gUInt32
First cheque book number.
-
chequeBookNumber2: gUInt32
Second cheque book number.
-
currency: gUInt32
Key of the associated currency.
-
defaultTemplate: gUInt32
Key of the default transaction template.
-
displayPosition: gUInt32
Display order position.
-
flags: gUShort
Bitmask of
ACCOUNT_FLAG_*values. -
key: gUInt32
Unique account key.
-
name: gCharP
Account name.
-
notes: gCharP
Free-text notes (may contain special characters).
-
overdraftLimit: gDouble
Overdraft limit (minimum balance).
-
startingBalance: gDouble
Initial / starting balance.
-
type: number
Account type (
ACCOUNT_TYPE_*constant).
A scheduled / recurring transaction template from the <fav> element.
-
account: gUInt32
Key of the source account.
-
amount: gDouble
Transaction amount.
-
category: gUInt32
Key of the category.
-
destinationAccount: gUInt32
Key of the destination account (for transfers).
-
flags: gUShort
Bitmask of
ARCHIVE_FLAG_*values. -
key: gUInt32
Unique archive key.
-
memo: gCharP
Transaction memo / description.
-
payMode: gUShort
Payment mode (
PAY_MODE_*constant). -
payee: gUInt32
Key of the payee.
-
scheduledEveryNumber: gUShort
Repeat every N units.
-
scheduledEveryUnit: gUShort
Repeat unit (
SCHEDULED_EVERY_UNIT_*constant). -
scheduledGap: gUShort
Gap in days before the next date to auto-insert.
-
scheduledNextDate: gUInt32
Next scheduled execution date (Julian day).
-
scheduledStopAfter: gUShort
Stop after this many occurrences (
0= unlimited). -
scheduledWeekend: gUShort
Weekend handling policy (
SCHEDULED_WEEKEND_*constant). -
splits: ArchiveSplit[]
Split transaction entries (when
ARCHIVE_FLAG_SPLITis set). -
status: gUShort
Transaction status (
ARCHIVE_STATUS_*constant). -
tags: gCharP[]
List of tag names.
A single entry within a split scheduled transaction.
-
amount: gDouble
Split amount.
-
category: gUInt32
Key of the split's category.
-
memo: gCharP
Split memo text.
An auto-assignment rule from the <asg> element.
-
category: gUInt32
Key of the category to assign.
-
field: gUShort
Field to match against (
ASSIGN_FIELD_*constant). -
flags: gUShort
Bitmask of
ASSIGN_FLAG_*values. -
key: gUInt32
Unique assign key.
-
name: gCharP
Pattern to match (text or regex depending on flags).
-
payMode: number
Payment mode to assign (
PAY_MODE_*constant). -
payee: gUInt32
Key of the payee to assign.
A transaction category from the <cat> element.
-
budgets: gDouble[]
Monthly budget amounts (up to 13 entries, indexed 0-12).
-
flags: gUShort
Bitmask of
CATEGORY_FLAG_*values. -
key: gUInt32
Unique category key.
-
name: gCharP
Category name.
-
parent: gUInt32
Key of the parent category (
0for top-level).
A currency definition from the <cur> element.
-
decimalCharacter: gCharP
Decimal separator character (e.g.
"."). -
exchangeRate: gDouble
Exchange rate relative to the base currency.
-
flags: gUShort
Bitmask of
CURRENCY_FLAG_*values. -
fractionDigits: gShort
Number of fractional digits to display.
-
groupingCharacter: gCharP
Thousands grouping character (e.g.
","). -
isoCode: gCharP
ISO 4217 currency code (e.g.
"USD","EUR"). -
key: gUInt32
Unique currency key.
-
lastUpdatedDate: gUInt32
Date the exchange rate was last updated (Julian day).
-
name: gCharP
Display name of the currency.
-
symbol: gCharP
Currency symbol (e.g.
"$","\u20AC"). -
symbolIsPrefixed: gBoolean
Whether the symbol is shown before the amount (
1) or after (0).
A financial transaction (operation) from the <ope> element.
-
account: gUInt32
Key of the source account.
-
amount: gDouble
Transaction amount.
-
category: gUInt32
Key of the category.
-
date: gUInt32
Transaction date as a Julian day number.
-
destinationAccount: gUInt32
Key of the destination account (for transfers).
-
flags: gUShort
Bitmask of
OPERATION_FLAG_*values. -
info: gCharP
Additional info (e.g. cheque number).
-
kxfer: gUInt32
Internal transfer key linking paired transfer transactions.
-
memo: gCharP
Transaction memo / description.
-
payMode: gUShort
Payment mode (
PAY_MODE_*constant). -
payee: gUInt32
Key of the payee.
-
splits: OperationSplit[]
Split transaction entries (when
OPERATION_FLAG_SPLITis set). -
status: gUShort
Transaction status (none, cleared, reconciled, remind).
-
tags: gCharP[]
List of tag names attached to this transaction.
A single entry within a split transaction.
-
amount: gDouble
Split amount.
-
category: gUInt32
Key of the split's category.
-
memo: gCharP
Split memo text.
A transaction payee from the <pay> element.
-
category: gUInt32
Default category key for this payee.
-
key: gUInt32
Unique payee key.
-
name: gCharP
Payee name.
-
payMode: gUShort
Default payment mode (
PAY_MODE_*constant).
Global file-level properties from the <properties> element.
-
baseCurrency: gUInt32
Key of the base (default) currency.
-
owner: gCharP
Owner name / file title.
-
vehicleCategory: gUInt32
Key of the vehicle expense category.
-
vehicleScheduledTransactionMode: gUShort
Vehicle scheduled transaction mode (
VEHICLE_SCHEDULED_TRANSACTION_MODE_WEEKDAYorVEHICLE_SCHEDULED_TRANSACTION_MODE_NUMBER_OF_DAYS). -
vehicleScheduledTransactionNumberOfDays: gUShort
Number of days gap for vehicle scheduled transactions.
-
vehicleScheduledTransactionWeekDay: gUShort
Day of week for vehicle scheduled transactions.
Options for serialize.
-
onEntity: <T>() => stringentity: T,serialized: string
Called for each serialized entity, allowing transformation of the XML output.
XHB file and data format version information from the <homebank> root element.
-
data: gInt
Data version as a 6-digit integer (e.g.
50800). -
file: gDouble
File format version string (e.g.
"1.4").
A complete HomeBank XHB file represented as a typed object.
-
accounts: Account[]
Bank accounts.
-
archives: Archive[]
Scheduled / recurring transaction templates.
-
assigns: Assign[]
Auto-assignment rules.
-
categories: Category[]
Transaction categories.
-
currencies: Currency[]
Currency definitions.
-
operations: Operation[]
Financial transactions.
-
payees: Payee[]
Transaction payees.
-
properties: Properties
Global file properties (owner, base currency, etc.).
-
tags: Tag[]
User-defined tags.
-
versions: Versions
File and data format version information.
Boolean stored as a number (0 or 1).
Null-terminated string (C gchar *).
Double-precision floating-point value stored as a string.
Signed 32-bit integer.
Signed 16-bit integer.
Unsigned 32-bit integer.
Unsigned 16-bit integer.
A partially-constructed XHB where only versions is required.
Used during parsing when the full object is still being built.
Account was recently added (temporary flag).
Account was recently changed (temporary flag).
Account is closed.
Exclude from budget.
Exclude from reports.
Exclude from summary.
Asset account.
Bank account.
Cash account.
Credit card account.
Liability (debt) account.
No account type.
Archive was recently added (temporary flag).
Archive is a scheduled (auto) transaction.
Archive was recently changed (temporary flag).
Use second cheque book numbering.
Transaction is income.
Scheduled transaction has a repeat limit.
Transaction contains split entries.
Cleared.
No status.
Reconciled.
Reminder.
Match against the memo field.
Match against the payee name.
Assign category on match.
Assign payment mode on match.
Assign payee on match.
Require exact match.
Overwrite existing category.
Overwrite existing payment mode.
Overwrite existing payee.
Pattern is a regular expression.
Category has budget amounts set.
Category has been user-customized.
Category budget is forced / overridden.
Category represents income (vs expense).
Category is a subcategory.
Currency has been user-customized.
Transaction was recently added (temporary flag).
Transaction was auto-generated from a schedule.
Transaction was recently changed (temporary flag).
Use second cheque book numbering.
Transaction is income.
Scheduled transaction has a repeat limit.
Transaction contains split entries.
Cash.
Credit card.
Check / cheque.
Debit card.
Deposit.
Direct debit.
Electronic payment.
Fee / charge.
Internal transfer between accounts.
No payment mode.
Total number of payment modes (upper bound sentinel).
Repeating / standing order payment.
Bank transfer.
Repeat every N days.
Repeat every N months.
Repeat every N weeks.
Repeat every N years.
Move to the Monday after if landing on a weekend.
Move to the Friday before if landing on a weekend.
Allow scheduling on weekends.
Vehicle scheduled transaction mode: repeat every N days.
Vehicle scheduled transaction mode: repeat on a specific weekday.
Legacy budget flag (pre-5.x).
Legacy remind flag (pre-5.x).
Legacy valid flag (pre-5.x).
Legacy remind flag (pre-5.x).
Legacy valid flag (pre-5.x).