# @os-team/xml-parser [![NPM version](https://img.shields.io/npm/v/@os-team/xml-parser)](https://yarnpkg.com/package/@os-team/xml-parser) [![BundlePhobia](https://img.shields.io/bundlephobia/minzip/@os-team/xml-parser)](https://bundlephobia.com/result?p=@os-team/xml-parser)

Converts XML to an object and back.
Fully complies with the [W3C XML recommendations (Fifth Edition)](https://www.w3.org/TR/xml/).

## Usage

Install the package using the following command:

```
yarn add @os-team/xml-parser
```

### Simple example

```ts
import { buildXml, parseXml } from '@os-team/xml-parser';

const data = { tag: 'text' };
const xml = buildXml(data); // <tag>text</tag>
const parsedData = parseXml(xml); // { tag: 'text' }
```

### Example with the XML declaration and attributes

```ts
import { buildXml, parseXml } from '@os-team/xml-parser';

const data: Document = {
  '#prolog': {
    xml: {
      version: '1.0',
      encoding: 'UTF-8',
    },
  },
  root: {
    first: 'text',
    second: {
      '#attrs': { id: '1' },
      '#content': 'text',
    },
  },
};
const xml = buildXml(data);
const parsedData = parseXml(xml, { include: 'ALL' }); // The same as the data
```

The output XML:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <first>text</first>
    <second id="1">text</second>
</root>
```

The `include` option determines whether attributes and prolog should be parsed. Can be:

- `ATTRIBUTES` – include tag attributes.
- `PROLOG` - include prolog.
- `ALL` - include tag attributes and prolog.

### Transform tag names

Sometimes XML tags are written in pascal case (e.g. MyTag). You can transform tag names as follows:

```ts
import { parseXml } from '@os-team/xml-parser';

const xml = '<MyTag>text</MyTag>';
const parsedData = parseXml(xml, {
  tagName: (name) => name.replace(/^\w/, (c) => c.toLowerCase()), // Make the tag name with a small letter
}); // { myTag: 'text' }
```

### Arrays

Almost any XML has an array. For example:

```xml
<root>
    <item>Item 1</item>
    <item>Item 2</item>
</root>
```

In this case, the library will detect that the same node occurs at least 2 times, so it must be an array.
Unfortunately, there is no way to automatically determine whether a node is an array if it occurs only 1 time.
For example:

```ts
import { parseXml } from '@os-team/xml-parser';

const xml = '<root><item>Item 1</item></root>';
const parsedData = parseXml(xml); // { root: { item: 'Item 1' } }
```

To solve this issue, you need to specify the `isArray` parameter to explicitly set the type of node as an array:

```ts
import { parseXml } from '@os-team/xml-parser';

const xml = '<root><item>Item 1</item></root>';
const parsedData = parseXml(xml, {
  isArray: ['item'],
}); // { root: { item: ['Item 1'] } }
```
