Advanced XML Utilities for TypeScript
A powerful and modular library for parsing, validating, and summarizing XML data.
Install via npm:
npm install nrc-phoenix-xml
Full API reference and usage examples are available at:
๐ https://nelsonrc.github.io/nrc-phoenix-xml/
parseXmlSummary(summaryStr: string): IXmlSummaryParses a summary string into a structured summary configuration.
summaryStr: Comma-separated configuration stringIXmlSummary objectimport { parseXmlSummary } from "nrc-phoenix-xml"
const summary = "Item,1,Category:Group,Price:Total Price:1,Qty:Count:3"
const result = parseXmlSummary(summary)
console.log(result)
{
"targetNode": "Item",
"orientation": 1,
"groupingField": "Category",
"groupingDisplayName": "Group",
"fields": [
{ "name": "Price", "displayName": "Total Price", "measure": 1 },
{ "name": "Qty", "displayName": "Count", "measure": 3 }
]
}
parseFormatOptions(optionsStr: string): IXmlSummaryFormatOptionsParses a compact options string into a formatting config object.
optionsStr: Key-value string (e.g. rd=2,cu=USD)IXmlSummaryFormatOptions objectimport { parseFormatOptions } from "nrc-phoenix-xml"
const config = "rd=2,cu=USD,sc=1,as=1,tm=0,sr=1,pf=Avg%|Rate%,if=Qty|Count"
const options = parseFormatOptions(config)
console.log(options)
{
"roundDecimals": 2,
"currency": "USD",
"showCurrencySymbol": true,
"asJson": true,
"treatMissingAsZero": false,
"sortResults": true,
"percentageFields": ["Avg%", "Rate%"],
"integerFields": ["Qty", "Count"]
}
parseSpecAndOptions(input: string, delimiter = ';'): { xmlSummaryStr, formatingOpts }Parses a combined string of summary + formatting into separate config objects.
input: "entry,1,*:Summary,total:Label:1;rd=2"delimiter: Optional separator (default: ;){ xmlSummaryStr: IXmlSummary, formatingOpts: IXmlSummaryFormatOptions }import { parseSpecAndOptions } from "nrc-phoenix-xml"
const input = "Item,2,Dept:Totals,Price:Price:1,Qty:Total Qty:3;rd=2,cu=USD,sc=1,as=1"
const { xmlSummaryStr, formatingOpts } = parseSpecAndOptions(input)
console.log({ xmlSummaryStr, formatingOpts })
{
"xmlSummaryStr": {
"targetNode": "Item",
"orientation": 2,
"groupingField": "Dept",
"groupingDisplayName": "Totals",
"fields": [
{ "name": "Price", "displayName": "Price", "measure": 1 },
{ "name": "Qty", "displayName": "Total Qty", "measure": 3 }
]
},
"formatingOpts": {
"roundDecimals": 2,
"currency": "USD",
"showCurrencySymbol": true,
"asJson": true
}
}
getSummaryFromXml(xml: string, spec: IXmlSummary, debug?: boolean, format?: IXmlSummaryFormatOptions): SummaryDictionary | stringGenerates an aggregated summary from raw XML, given a structured spec.
xml: Raw XML stringspec: Parsed summary definitiondebug: Optional diagnostic outputformat: Formatting preferencesasJson flagimport { XmlSummarizer, parseXmlSummary, parseFormatOptions } from "nrc-phoenix-xml"
const xml = `<items>
<item><category>A</category><price>10.5</price><qty>2</qty></item>
<item><category>A</category><price>5.0</price><qty>1</qty></item>
<item><category>B</category><price>12.0</price><qty>3</qty></item>
</items>`
const summarySpec = parseXmlSummary("item,1,category:Category,price:Total Price:1,qty:Count:3")
const formatOptions = parseFormatOptions("rd=2,cu=USD,sc=1,as=1")
const result = XmlSummarizer.getSummaryFromXml(xml, summarySpec, false, formatOptions)
console.log(result)
{
"Category": {
"A": [
{ "name": "Total Price", "value": "$15.50" },
{ "name": "Count", "value": 3 }
],
"B": [
{ "name": "Total Price", "value": "$12.00" },
{ "name": "Count", "value": 3 }
]
}
}
processXmlSummary(xml: string, summaryStr: string, debug?: boolean, format?: IXmlSummaryFormatOptions): SummaryDictionary | stringSimplified method that parses and summarizes XML data in one step.
xml: XML stringsummaryStr: Configuration stringdebug: Show debug logs (optional)format: Output optionsimport { XmlSummarizer } from "nrc-phoenix-xml"
const xmlData = `<sales>
<entry><region>North</region><total>1250.50</total></entry>
<entry><region>North</region><total>470.25</total></entry>
<entry><region>South</region><total>815.75</total></entry>
</sales>`
const summaryStr = "entry,1,region:Region,total:Total Sales:1"
const format = {
roundDecimals: 2,
currency: "USD",
showCurrencySymbol: true,
asJson: true,
sortResults: true
}
const result = XmlSummarizer.processXmlSummary(xmlData, summaryStr, false, format)
console.log(result)
{
"Region": {
"North": [
{ "name": "Total Sales", "value": "$1,720.75" }
],
"South": [
{ "name": "Total Sales", "value": "$815.75" }
]
}
}
The summaryString parameter follows a comma-separated structure, defining XML elements and their aggregation behavior.
elementName,summaryOrientation,groupingField,groupingDisplayName,attribute1:Label1:aggregationType,attribute2:Label2:aggregationType
elementName โ Target parent XML element for summarization.summaryOrientation โ Reserved for future versions to define how summaries are organized (currently unused).groupingField โ Defines the field used for grouping. If "*", there is no grouping.groupingDisplayName โ Specifies the key returned in the result, representing the groupingField. If groupingField == "*", this acts as the general summary name.attribute:Label:aggregationMeasure โ Specifies attributes, labels, and aggregation methods.transaction,1,portfolio_type:Portfolio type,acquisition_value:Acquisition value:1,market_value:Market value:1
transaction โ XML element being processed.1 โ summaryOrientation, reserved for future use.portfolio_type โ Used for grouping (e.g., "A" and "B").Portfolio type โ The label returned in the result representing portfolio_type.acquisition_value โ Summarized field representing acquisition value.Acquisition value โ Label assigned to acquisition_value in the summary result.market_value โ Summarized field representing market value.Market value โ Label assigned to market_value in the summary result.{
"Portfolio type": {
"A": [
{ "name": "Acquisition value", "value": "$1,000.75" },
{ "name": "Market value", "value": "$1,050.50" }
],
"B": [
{ "name": "Acquisition value", "value": "$500.50" },
{ "name": "Market value", "value": "$520.80" }
]
}
}
| Code | Name | Description |
|---|---|---|
1 |
Sum | Adds all values together |
2 |
Count | Counts the number of occurrences |
3 |
Min | Finds the smallest value |
4 |
Max | Finds the largest value |
5 |
Average | Calculates the mean of values |
6 |
Standard Deviation | Measures how spread out the values are |
| Key | Option | Type | Description |
|---|---|---|---|
rd |
roundDecimals |
number |
Decimal precision to round summarized values |
cu |
currency |
string |
ISO currency code (e.g., USD, EUR) |
sc |
showCurrencySymbol |
boolean |
Show currency symbol (1 = true, 0 = false) |
as |
asJson |
boolean |
Output as JSON (1 = true) or string |
tm |
treatMissingAsZero |
boolean |
Handle empty fields as zero when aggregating |
sr |
sortResults |
boolean |
Sort summary output by display name |
pf |
percentageFields |
string[] |
List of fields treated as percentages (pipe-separated) |
if |
integerFields |
string[] |
List of fields treated as whole numbers (pipe-separated) |
The tools/ directory contains handy shell scripts that simplify common tasks such as initializing the repo, generating documentation, and deploying updates to GitHub Pages.
deploy-docs.shGenerates and deploys the API documentation to the gh-pages branch.
./tools/deploy-docs.sh
typedoc and typedoc.json configcommit-and-deploy.shCommits staged changes and redeploys documentation in one command.
./tools/commit-and-deploy.sh "Update docs and push latest changes"
init-repo.sh./tools/init-repo.sh
chmod +x ./tools/*.sh
Then you can run them directly, or include them in your package.json:
"scripts": {
"docs": "typedoc",
"docs:deploy": "./tools/deploy-docs.sh",
"init": "./tools/init-repo.sh"
}
๐ก Keep these scripts modular and version-controlled to support reproducible builds and deployments.
Unit and functional tests are located in the tests/ directory to ensure correctness, scalability, and resilience of core features.
npm run test
For watch mode during development:
npx jest --watch
npx jest tests/XmlSummarizer.test.ts
tests/
โโโ XmlSummarizer.test.ts # Tests for summary computation logic
โโโ parseXmlSummary.test.ts # Tests for summary string parsing
โโโ parseFormatOptions.test.ts # Tests for format configuration parsing
โโโ parseSpecAndOptions.test.ts # Tests for combined parsing
Each test uses Jest and follows the .test.ts naming convention for discoverability.
npx jest --coverage
Reports will appear in the coverage/ folder.
We welcome contributions to improve nrc-phoenix-xml! To contribute:
Fork the repository:
git clone https://github.com/nelsonrc/nrc-phoenix-xml.git
Install dependencies:
npm install
Create a feature branch:
git checkout -b feature/new-functionality
Submit a Pull Request ๐
This project is licensed under the MIT License. See LICENSE for details.
For issues or support, visit GitHub Issues.