npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@nelsonrc/nrc-phoenix-xml

v1.0.3

Published

A declarative XML summarizer with formatting logic for Angular apps and automation workflows.

Readme

nrc-phoenix-xml

Advanced XML Utilities for TypeScript
A powerful and modular library for parsing, validating, and summarizing XML data.

🚀 Features

  • XML Parsing & Validation with XSD support
  • Data Summarization with configurable aggregation methods
  • Data Summarization of same field with different measures
  • Modular and Scalable Architecture
  • Localization Support (e.g., currency & percentage formatting)
  • Built-in Error Handling and Debugging

📦 Installation

Install via npm:

npm install nrc-phoenix-xml

📘 Documentation

Full API reference and usage examples are available at:

👉 https://nelsonrc.github.io/nrc-phoenix-xml/


🔹 parseXmlSummary(summaryStr: string): IXmlSummary

Parses a summary string into a structured summary configuration.

  • summaryStr: Comma-separated configuration string
  • Returns: IXmlSummary object
  • Throws: Error if string is malformed

🔹 Code

import { 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)

🔹 Output

{
  "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): IXmlSummaryFormatOptions

Parses a compact options string into a formatting config object.

  • optionsStr: Key-value string (e.g. rd=2,cu=USD)
  • Returns: IXmlSummaryFormatOptions object

🔹 Code

import { 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)

🔹 Output

{
  "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: ;)
  • Returns: { xmlSummaryStr: IXmlSummary, formatingOpts: IXmlSummaryFormatOptions }
  • Throws: Error if either part is missing

🔹 Code

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

🔹 Output

{
  "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 | string

Generates an aggregated summary from raw XML, given a structured spec.

  • xml: Raw XML string
  • spec: Parsed summary definition
  • debug: Optional diagnostic output
  • format: Formatting preferences
  • Returns: Object or JSON string based on asJson flag

🔹 Code

import { 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)

🔹 Output

{
  "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 | string

Simplified method that parses and summarizes XML data in one step.

  • xml: XML string
  • summaryStr: Configuration string
  • debug: Show debug logs (optional)
  • format: Output options
  • Returns: Summary data grouped by field or JSON string

🔹 Code

import { 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)

🔹 Output

{
  "Region": {
    "North": [
      { "name": "Total Sales", "value": "$1,720.75" }
    ],
    "South": [
      { "name": "Total Sales", "value": "$815.75" }
    ]
  }
}

📝 Summary String Format

The summaryString parameter follows a comma-separated structure, defining XML elements and their aggregation behavior.

📌 Format:

elementName,summaryOrientation,groupingField,groupingDisplayName,attribute1:Label1:aggregationType,attribute2:Label2:aggregationType

🔹 Explanation

  • 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.

🔹 Example Summary String

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.

🔹 Expected Output

{
    "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" }
        ]
    }
}

📊 Aggregation Measures

| Code | Name | Description | |----------|----------------------|--------------------------------------------------| | 1 | Sum | Adds all values together | | 2 | Average | Calculates the mean of values | | 3 | Count | Counts the number of occurrences | | 4 | Min | Finds the smallest value | | 5 | Max | Finds the largest value | | 6 | Standard Deviation | Measures how spread out the values are |

🧩 Format Options Reference

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

🛠 Tools & Scripts

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.sh

Generates and deploys the API documentation to the gh-pages branch.

./tools/deploy-docs.sh
  • Uses typedoc and typedoc.json config
  • Automatically switches branches and pushes updates
  • Safe for manual and CI/CD usage

🔹 commit-and-deploy.sh

Commits staged changes and redeploys documentation in one command.

./tools/commit-and-deploy.sh "Update docs and push latest changes"
  • Stages and commits current updates
  • Calls deploy-docs.sh afterward
  • Useful for quick publishing cycles

🔹 init-repo.sh

./tools/init-repo.sh

🧰 Usage Tips

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.

📦 Tests

Unit and functional tests are located in the tests/ directory to ensure correctness, scalability, and resilience of core features.

🧪 Running All Tests

npm run test

For watch mode during development:

npx jest --watch

▶️ Run Specific Test File

npx jest tests/XmlSummarizer.test.ts

📂 Structure

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.

📊 Optional: Code Coverage

npx jest --coverage

Reports will appear in the coverage/ folder.

💡 Tip: Grouping-related tests can live under tests/groups/, while shared mocks can go in tests/utils/.

🏗️ Contribution Guidelines

🔹 How to Contribute

We welcome contributions to improve nrc-phoenix-xml! To contribute:

  1. Fork the repository:

    git clone https://github.com/nelsonrc/nrc-phoenix-xml.git
  2. Install dependencies:

    npm install
  3. Create a feature branch:

    git checkout -b feature/new-functionality
  4. Submit a Pull Request 🚀

📜 License

This project is licensed under the MIT License. See LICENSE for details.

📞 Support & Issues

For issues or support, visit GitHub Issues.