@office-open/xml 0.10.15 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -89
- package/dist/index.d.mts +6 -20
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +323 -379
- package/dist/index.mjs.map +1 -1
- package/dist/{utils-BFKTfRa8.d.mts → utils-qhk6IlD8.d.mts} +8 -36
- package/dist/utils-qhk6IlD8.d.mts.map +1 -0
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +11 -3
- package/dist/utils.mjs.map +1 -1
- package/package.json +8 -4
- package/dist/utils-BFKTfRa8.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -5,17 +5,15 @@
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
|
|
8
|
-
> XML parsing and serialization for Office Open XML. Zero dependencies,
|
|
8
|
+
> XML parsing and serialization for Office Open XML. Zero dependencies, pure TypeScript.
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
12
|
- **Zero Dependencies** - No external runtime dependencies, pure TypeScript implementation
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **Complete Type Definitions** - Full type compatibility with `xml` and `xml-js`, import without changes
|
|
18
|
-
- **OOXML Optimized** - Implements all options needed for Office Open XML document generation
|
|
13
|
+
- **parse() / stringify()** - XML string ↔ Element tree, OOXML-optimized
|
|
14
|
+
- **Element Type** - Tolerant element model for round-tripping Office Open XML parts
|
|
15
|
+
- **escapeXml() / unescapeXml()** - Low-level XML entity escaping
|
|
16
|
+
- **OOXML Optimized** - Implements the options needed for Office Open XML document generation and parsing
|
|
19
17
|
|
|
20
18
|
## Installation
|
|
21
19
|
|
|
@@ -33,113 +31,72 @@ yarn add @office-open/xml
|
|
|
33
31
|
bun add @office-open/xml
|
|
34
32
|
```
|
|
35
33
|
|
|
36
|
-
## Migration from xml + xml-js
|
|
37
|
-
|
|
38
|
-
Replace your existing imports:
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
// Before
|
|
42
|
-
import xml from "xml";
|
|
43
|
-
import { xml2js, js2xml } from "xml-js";
|
|
44
|
-
import type { Element } from "xml-js";
|
|
45
|
-
|
|
46
|
-
// After
|
|
47
|
-
import { xml, xml2js, js2xml } from "@office-open/xml";
|
|
48
|
-
import type { Element } from "@office-open/xml";
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
No other code changes needed. All options and output formats are compatible.
|
|
52
|
-
|
|
53
34
|
## Quick Start
|
|
54
35
|
|
|
55
36
|
```typescript
|
|
56
|
-
import {
|
|
57
|
-
|
|
58
|
-
// Serialize JS objects to XML
|
|
59
|
-
const xmlStr = xml({ "w:p": [{ _attr: { "w:val": "1" } }, { "w:r": [{ "w:t": "Hello" }] }] });
|
|
60
|
-
// <w:p w:val="1"><w:r><w:t>Hello</w:t></w:r></w:p>
|
|
61
|
-
|
|
62
|
-
// Parse XML to JS objects
|
|
63
|
-
const parsed = xml2js("<w:t>Hello</w:t>", { compact: false });
|
|
37
|
+
import { parse, stringify } from "@office-open/xml";
|
|
64
38
|
|
|
65
|
-
//
|
|
66
|
-
const
|
|
39
|
+
// Parse XML to an Element tree
|
|
40
|
+
const doc = parse("<w:t>Hello</w:t>");
|
|
67
41
|
|
|
68
|
-
//
|
|
69
|
-
const
|
|
70
|
-
"w:p": [{ _attr: { "w:val": "1" } }, { "w:r": [{ "w:t": "Hello" }] }],
|
|
71
|
-
});
|
|
42
|
+
// Serialize an Element tree back to XML
|
|
43
|
+
const xml = stringify(doc);
|
|
72
44
|
```
|
|
73
45
|
|
|
74
46
|
## API
|
|
75
47
|
|
|
76
|
-
###
|
|
77
|
-
|
|
78
|
-
Serialize JavaScript objects to XML string. Compatible with the `xml` package.
|
|
79
|
-
|
|
80
|
-
### xml2js(xmlString, options?)
|
|
48
|
+
### parse(xmlString, options?)
|
|
81
49
|
|
|
82
|
-
Parse XML string
|
|
50
|
+
Parse an XML string into an `Element` tree. Options include `compact`, `trim`, `nativeType`, `captureSpacesBetweenElements`, the `ignore*` flags, and the `*Fn` transformation hooks.
|
|
83
51
|
|
|
84
|
-
###
|
|
52
|
+
### stringify(element, options?)
|
|
85
53
|
|
|
86
|
-
|
|
54
|
+
Serialize an `Element` tree to an XML string. Options include `spaces` (indentation), the `ignore*` flags, and the `*Fn` hooks.
|
|
87
55
|
|
|
88
|
-
###
|
|
56
|
+
### escapeXml(str) / unescapeXml(str)
|
|
89
57
|
|
|
90
|
-
|
|
58
|
+
Low-level XML entity escaping and unescaping.
|
|
91
59
|
|
|
92
|
-
###
|
|
60
|
+
### Element
|
|
93
61
|
|
|
94
|
-
|
|
62
|
+
The tolerant element type used across all office-open packages:
|
|
95
63
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
64
|
+
```typescript
|
|
65
|
+
interface Element {
|
|
66
|
+
declaration?: { attributes?: DeclarationAttributes };
|
|
67
|
+
attributes?: Attributes;
|
|
68
|
+
type?: string;
|
|
69
|
+
name?: string;
|
|
70
|
+
text?: string | number | boolean;
|
|
71
|
+
cdata?: string;
|
|
72
|
+
comment?: string;
|
|
73
|
+
elements?: Element[];
|
|
74
|
+
}
|
|
75
|
+
```
|
|
103
76
|
|
|
104
77
|
## Benchmark
|
|
105
78
|
|
|
106
|
-
Performance
|
|
107
|
-
|
|
108
|
-
### Serialization (xml)
|
|
109
|
-
|
|
110
|
-
| Scenario | @office-open/xml | xml | Speedup |
|
|
111
|
-
| ----------------------- | ---------------: | ---------: | --------: |
|
|
112
|
-
| Simple element | 5,440,771 hz | 805,545 hz | **6.75x** |
|
|
113
|
-
| Nested element | 1,050,272 hz | 315,184 hz | **3.33x** |
|
|
114
|
-
| Nested with declaration | 967,945 hz | 275,684 hz | **3.51x** |
|
|
115
|
-
|
|
116
|
-
### Parsing (xml2js)
|
|
117
|
-
|
|
118
|
-
| Scenario | @office-open/xml | xml-js | Speedup |
|
|
119
|
-
| ------------------ | ---------------: | ---------: | --------: |
|
|
120
|
-
| Simple XML | 869,965 hz | 100,507 hz | **8.66x** |
|
|
121
|
-
| Complex OOXML | 346,440 hz | 53,621 hz | **6.46x** |
|
|
122
|
-
| With captureSpaces | 344,586 hz | 52,414 hz | **6.57x** |
|
|
123
|
-
|
|
124
|
-
### Stringifying (js2xml)
|
|
79
|
+
Performance vs [txml](https://github.com/TobiasNickel/tXml), [xml-js](https://github.com/nashwaan/xml-js), and [xml](https://github.com/dylang/node-xml) (higher ops/s is better, Windows 11; each scenario runs under both Node 24 and Bun 1.4). `@office-open/xml` is a drop-in replacement for xml-js and xml. The `xml` (npm) package is generation-only (no parser), so it only appears under stringify. `Bun.XML` is Bun-only and its compact parse mode is lossy (`#text` runs concatenate, same-name children collapse into keyed arrays), so it is a throughput reference rather than a drop-in option.
|
|
125
80
|
|
|
126
|
-
|
|
127
|
-
| -------------- | ---------------: | ---------: | --------: |
|
|
128
|
-
| Simple element | 793,710 hz | 207,730 hz | **3.82x** |
|
|
129
|
-
| Complex OOXML | 366,515 hz | 135,815 hz | **2.70x** |
|
|
81
|
+
txml skips entity encoding by default (`encodeEntities: false`), which emits invalid XML when text contains `&`, `<`, or `>`; the `txml` column shows that raw mode and the `txml (entities)` column is the output-equivalent mode.
|
|
130
82
|
|
|
131
|
-
|
|
83
|
+
**parse() — XML string → Element tree**
|
|
132
84
|
|
|
133
|
-
| Scenario
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
85
|
+
| Scenario | Runtime | @office-open/xml | txml | xml-js | Bun.XML.parse |
|
|
86
|
+
| ------------- | ------- | ---------------- | ------------- | ------------- | ------------- |
|
|
87
|
+
| simple XML | Node 24 | 1,301,742 ops/s | 983,046 ops/s | 93,951 ops/s | — |
|
|
88
|
+
| | Bun 1.4 | 1,906,525 ops/s | 616,562 ops/s | 161,894 ops/s | 828,554 ops/s |
|
|
89
|
+
| complex OOXML | Node 24 | 423,536 ops/s | 388,743 ops/s | 49,771 ops/s | — |
|
|
90
|
+
| | Bun 1.4 | 483,512 ops/s | 241,036 ops/s | 63,029 ops/s | 451,177 ops/s |
|
|
137
91
|
|
|
138
|
-
|
|
92
|
+
**stringify() — Element tree → XML string**
|
|
139
93
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
94
|
+
| Scenario | Runtime | @office-open/xml | txml (entities) | txml | xml-js | xml (npm) | Bun.XML.stringify |
|
|
95
|
+
| -------------- | ------- | ---------------- | --------------- | --------------- | ------------- | ------------- | ----------------- |
|
|
96
|
+
| simple element | Node 24 | 2,049,617 ops/s | 1,255,456 ops/s | 2,765,770 ops/s | 190,783 ops/s | 303,724 ops/s | — |
|
|
97
|
+
| | Bun 1.4 | 2,588,728 ops/s | 1,721,498 ops/s | 4,248,377 ops/s | 438,430 ops/s | 483,526 ops/s | 584,746 ops/s |
|
|
98
|
+
| complex OOXML | Node 24 | 583,811 ops/s | 447,274 ops/s | 1,326,397 ops/s | 130,335 ops/s | 172,258 ops/s | — |
|
|
99
|
+
| | Bun 1.4 | 510,448 ops/s | 528,375 ops/s | 2,303,173 ops/s | 226,645 ops/s | 292,534 ops/s | 251,444 ops/s |
|
|
143
100
|
|
|
144
101
|
## License
|
|
145
102
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/serialize.d.ts
|
|
4
|
-
declare function xml(input: Record<string, unknown> | Record<string, unknown>[], options?: boolean | string | {
|
|
5
|
-
indent?: boolean | string;
|
|
6
|
-
declaration?: boolean | {
|
|
7
|
-
encoding?: string;
|
|
8
|
-
standalone?: string;
|
|
9
|
-
};
|
|
10
|
-
}): string;
|
|
11
|
-
//#endregion
|
|
1
|
+
import { C as IgnoreOptions, S as ElementCompact, T as StringifyOptions, _ as isNonEmpty, a as attrBool, b as DeclarationAttributes, c as childCount, d as collectText, f as colorAttr, g as hasChild, h as findFirst, i as attr, l as childText, m as findDeep, n as OOXML_XML_DECLARATION, o as attrMeasure, p as findChild, r as allChildren, s as attrNum, t as NonEmptyArray, u as children, v as textOf, w as ParseOptions, x as Element, y as Attributes } from "./utils-qhk6IlD8.mjs";
|
|
12
2
|
//#region src/parse.d.ts
|
|
13
3
|
declare function unescapeXml(str: string): string;
|
|
14
4
|
declare function nativeTypeValue(value: string): string | number | boolean;
|
|
15
|
-
declare function parse(xmlString: string, options?:
|
|
5
|
+
declare function parse(xmlString: string, options?: ParseOptions): Element;
|
|
16
6
|
declare function parseAttributes(str: string): Record<string, string>;
|
|
17
7
|
//#endregion
|
|
18
8
|
//#region src/stringify.d.ts
|
|
19
|
-
declare function stringify(js: Element, options?:
|
|
20
|
-
declare function json2xml(json: Element, options?: Js2XmlOptions): string;
|
|
9
|
+
declare function stringify(js: Element, options?: StringifyOptions): string;
|
|
21
10
|
//#endregion
|
|
22
|
-
//#region src/
|
|
23
|
-
declare function
|
|
11
|
+
//#region src/stringify-element.d.ts
|
|
12
|
+
declare function stringifyElement(el: Element): string;
|
|
24
13
|
//#endregion
|
|
25
14
|
//#region src/escape.d.ts
|
|
26
15
|
declare function escapeXml(str: string): string;
|
|
@@ -29,8 +18,5 @@ declare function attrsRaw(record: Record<string, string | number | boolean | und
|
|
|
29
18
|
declare function selfCloseElement(tag: string, attrStr?: string): string;
|
|
30
19
|
declare function element(name: string, attrRecord?: Readonly<Record<string, string | number | boolean | undefined>>, children?: readonly string[]): string;
|
|
31
20
|
//#endregion
|
|
32
|
-
|
|
33
|
-
declare function xml2json(xml: string, options?: Xml2JsOptions): string;
|
|
34
|
-
//#endregion
|
|
35
|
-
export { type Attributes, type DeclarationAttributes, type Element, type ElementCompact, type ElementObject, type IgnoreOptions, type Js2XmlOptions, NonEmptyArray, type Xml2JsOptions, type XmlAtom, type XmlAttrs, type XmlDesc, type XmlDescArray, type XmlObject, type XmlOption, allChildren, attr, attrBool, attrMeasure, attrNum, attrs, attrsRaw, childCount, childText, children, collectText, colorAttr, element, escapeXml, findChild, findDeep, findFirst, hasChild, isNonEmpty, stringify as js2xml, stringify, json2xml, nativeTypeValue, parse, parse as xml2js, parseAttributes, selfCloseElement, textOf, toElement, unescapeXml, xml, xml2json };
|
|
21
|
+
export { type Attributes, type DeclarationAttributes, type Element, type ElementCompact, type IgnoreOptions, NonEmptyArray, OOXML_XML_DECLARATION, type ParseOptions, type StringifyOptions, allChildren, attr, attrBool, attrMeasure, attrNum, attrs, attrsRaw, childCount, childText, children, collectText, colorAttr, element, escapeXml, findChild, findDeep, findFirst, hasChild, isNonEmpty, nativeTypeValue, parse, parseAttributes, selfCloseElement, stringify, stringifyElement, textOf, unescapeXml };
|
|
36
22
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/parse.ts","../src/stringify.ts","../src/stringify-element.ts","../src/escape.ts"],"mappings":";;iBAagB,YAAY;iBAgBZ,gBAAgB;iBA4ChB,MAAM,mBAAmB,UAAU,eAAe;iBAwXlD,gBAAgB,cAAc;;;iBC1b9B,UAAU,IAAI,SAAS,UAAU;;;iBCIjC,iBAAiB,IAAI;;;iBCPrB,UAAU;iBA6BV,MAAM,QAAQ;iBAsBd,SAAS,QAAQ;iBAejB,iBAAiB,aAAa;iBAoB9B,QACd,cACA,aAAa,SAAS,wDACtB"}
|