xml-to-html-converter 0.3.1 → 0.4.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 +92 -72
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +10 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,72 +6,49 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
|
-
A zero-dependency Node.js package for converting XML to HTML.
|
|
9
|
+
A zero-dependency Node.js package for converting XML to HTML.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- **`minify(xml)`** strips inter-tag whitespace from prettified XML before parsing. Text content is left untouched
|
|
12
|
+
- **`scaffold(xml)`** reads any XML string and returns a nested node tree
|
|
13
|
+
- **`walk(nodes, visitor)`** traverses the full node tree depth-first, visiting every node
|
|
14
|
+
- **`render(nodes)`** converts a node tree to an HTML string. Every XML element becomes a `<div>` with `data-tag` and `data-attrs-*` attributes
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
---
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
## Install
|
|
16
19
|
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
name: string;
|
|
20
|
-
value: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface XmlNode {
|
|
24
|
-
role: XmlNodeRole;
|
|
25
|
-
raw: string;
|
|
26
|
-
xmlTag?: string;
|
|
27
|
-
xmlInner?: string;
|
|
28
|
-
xmlAttributes?: XmlAttribute[];
|
|
29
|
-
globalIndex: number;
|
|
30
|
-
localIndex: number;
|
|
31
|
-
children?: XmlNode[];
|
|
32
|
-
malformed?: true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type XmlNodeRole =
|
|
36
|
-
| "closeTag"
|
|
37
|
-
| "comment"
|
|
38
|
-
| "doctype"
|
|
39
|
-
| "openTag"
|
|
40
|
-
| "processingInstruction"
|
|
41
|
-
| "selfTag"
|
|
42
|
-
| "textLeaf";
|
|
20
|
+
```bash
|
|
21
|
+
npm install xml-to-html-converter
|
|
43
22
|
```
|
|
44
23
|
|
|
45
|
-
This scaffold is the foundation everything else will be built on. No transformation, no HTML output, no opinions about content, just an accurate, traversable representation of what the XML says.
|
|
46
|
-
|
|
47
24
|
---
|
|
48
25
|
|
|
49
|
-
|
|
50
|
-
>
|
|
51
|
-
> `v0.x` is building the scaffold and the first render pass.
|
|
52
|
-
>
|
|
53
|
-
> - **`minify(xml)`** strips inter-tag whitespace from prettified XML before parsing — text content is left untouched
|
|
54
|
-
> - **`scaffold(xml)`** reads any XML string and returns a nested node tree
|
|
55
|
-
> - Every node knows its `role`, its `raw` source string, its `globalIndex` in the document, and its `localIndex` within its parent
|
|
56
|
-
> - Tag nodes (`openTag`, `selfTag`) also carry `xmlTag`, `xmlInner`, and `xmlAttributes` — the parsed tag name, raw attribute string, and structured attribute array
|
|
57
|
-
> - Broken XML is never thrown — malformed nodes are flagged with `malformed: true` in place and the tree is built regardless
|
|
58
|
-
> - **`render(nodes)`** takes the scaffold output and converts it to an HTML string — every XML element becomes a `<div>` with `data-tag` and `data-attrs-*` attributes
|
|
59
|
-
>
|
|
60
|
-
> `v1.0.0` is when this package becomes what it says it is: a full XML-to-HTML converter. Everything before that is the work to get there.
|
|
26
|
+
## Usage
|
|
61
27
|
|
|
62
|
-
|
|
28
|
+
### minify
|
|
63
29
|
|
|
64
|
-
|
|
30
|
+
When your XML comes from a file or an API it is usually indented and line-broken. `minify` strips the whitespace between tags before parsing. Text content is left completely untouched.
|
|
65
31
|
|
|
66
|
-
```
|
|
67
|
-
|
|
32
|
+
```js
|
|
33
|
+
import { minify } from "xml-to-html-converter";
|
|
34
|
+
|
|
35
|
+
const clean = minify(`
|
|
36
|
+
<bookstore>
|
|
37
|
+
<book category="cooking">
|
|
38
|
+
<title lang="en">Everyday Italian</title>
|
|
39
|
+
</book>
|
|
40
|
+
</bookstore>
|
|
41
|
+
`);
|
|
42
|
+
// <bookstore><book category="cooking"><title lang="en">Everyday Italian</title></book></bookstore>
|
|
68
43
|
```
|
|
69
44
|
|
|
45
|
+
`minify` is opt-in. Skip it if whitespace inside your content is meaningful.
|
|
46
|
+
|
|
70
47
|
---
|
|
71
48
|
|
|
72
|
-
|
|
49
|
+
### scaffold
|
|
73
50
|
|
|
74
|
-
|
|
51
|
+
`scaffold` parses an XML string into a structured tree of `XmlNode` objects. Each node carries its role, its raw source text, and its position in the document both globally across the full document and locally within its parent.
|
|
75
52
|
|
|
76
53
|
```js
|
|
77
54
|
import { scaffold } from "xml-to-html-converter";
|
|
@@ -135,7 +112,43 @@ const tree = scaffold(`
|
|
|
135
112
|
]
|
|
136
113
|
```
|
|
137
114
|
|
|
138
|
-
|
|
115
|
+
`scaffold` never throws. Malformed structures are flagged with `malformed: true` in place and the tree is built regardless. See [Malformed XML](#malformed-xml) for details.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### walk
|
|
120
|
+
|
|
121
|
+
`walk` traverses the full node tree depth-first, calling a visitor function on every node including all descendants. The visitor decides what to collect or do. `walk` has no opinions.
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
import { scaffold, walk } from "xml-to-html-converter";
|
|
125
|
+
|
|
126
|
+
const tree = scaffold(xml);
|
|
127
|
+
|
|
128
|
+
// collect all text content
|
|
129
|
+
const text = [];
|
|
130
|
+
walk(tree, (node) => {
|
|
131
|
+
if (node.role === "textLeaf") text.push(node.raw);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// find all nodes with a specific tag
|
|
135
|
+
const titles = [];
|
|
136
|
+
walk(tree, (node) => {
|
|
137
|
+
if (node.xmlTag === "title") titles.push(node);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// check for malformed nodes anywhere in the tree
|
|
141
|
+
const broken = [];
|
|
142
|
+
walk(tree, (node) => {
|
|
143
|
+
if (node.malformed) broken.push(node);
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### render
|
|
150
|
+
|
|
151
|
+
`render` walks the node tree and converts every XML element to a `<div>`. The original tag name is preserved in `data-tag` and each attribute becomes its own `data-attrs-*` attribute.
|
|
139
152
|
|
|
140
153
|
```js
|
|
141
154
|
import { scaffold, render } from "xml-to-html-converter";
|
|
@@ -151,8 +164,6 @@ const html = render(
|
|
|
151
164
|
);
|
|
152
165
|
```
|
|
153
166
|
|
|
154
|
-
`render` walks the node tree and converts every XML element to a `<div>`. The original tag name is preserved in `data-tag` and each attribute becomes its own `data-attrs-*` attribute:
|
|
155
|
-
|
|
156
167
|
```html
|
|
157
168
|
<div data-tag="bookstore">
|
|
158
169
|
<div data-tag="book" data-attrs-category="cooking">
|
|
@@ -165,17 +176,19 @@ Processing instructions and doctypes are dropped. Comments are passed through un
|
|
|
165
176
|
|
|
166
177
|
---
|
|
167
178
|
|
|
168
|
-
###
|
|
169
|
-
|
|
170
|
-
When your XML comes from a file or an API it is usually indented and line-broken. `minify` strips the whitespace between tags before parsing, leaving text content completely untouched.
|
|
179
|
+
### Full pipeline
|
|
171
180
|
|
|
172
181
|
```js
|
|
173
|
-
import { minify, scaffold, render } from "xml-to-html-converter";
|
|
182
|
+
import { minify, scaffold, walk, render } from "xml-to-html-converter";
|
|
174
183
|
|
|
175
|
-
const
|
|
176
|
-
```
|
|
184
|
+
const tree = scaffold(minify(xml));
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
walk(tree, (node) => {
|
|
187
|
+
if (node.malformed) console.warn("malformed node", node.raw);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const html = render(tree);
|
|
191
|
+
```
|
|
179
192
|
|
|
180
193
|
---
|
|
181
194
|
|
|
@@ -187,7 +200,7 @@ Every node in the tree has the following fields:
|
|
|
187
200
|
| --------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
188
201
|
| `role` | `XmlNodeRole` | What kind of node this is |
|
|
189
202
|
| `raw` | `string` | The exact source string, untouched |
|
|
190
|
-
| `xmlTag` | `string` | Tag name only, e.g. `"book"` or `"env:Envelope"`. Present on `openTag`, `selfTag`, `closeTag`
|
|
203
|
+
| `xmlTag` | `string` | Tag name only, e.g. `"book"` or `"env:Envelope"`. Present on `openTag`, `selfTag`, and `closeTag` |
|
|
191
204
|
| `xmlInner` | `string` | Everything after the tag name inside the brackets, verbatim. Present on `openTag` and `selfTag` when attributes exist |
|
|
192
205
|
| `xmlAttributes` | `XmlAttribute[]` | Parsed array of `{ name, value }` attribute objects. Present on `openTag` and `selfTag` when attributes exist |
|
|
193
206
|
| `globalIndex` | `number` | Position in the entire document (never resets) |
|
|
@@ -268,7 +281,13 @@ const tree = scaffold("<root><unclosed><valid>text</valid></root>");
|
|
|
268
281
|
## Exports
|
|
269
282
|
|
|
270
283
|
```ts
|
|
271
|
-
import {
|
|
284
|
+
import {
|
|
285
|
+
minify,
|
|
286
|
+
scaffold,
|
|
287
|
+
walk,
|
|
288
|
+
render,
|
|
289
|
+
isMalformed,
|
|
290
|
+
} from "xml-to-html-converter";
|
|
272
291
|
import type {
|
|
273
292
|
XmlNode,
|
|
274
293
|
XmlNodeRole,
|
|
@@ -277,16 +296,17 @@ import type {
|
|
|
277
296
|
} from "xml-to-html-converter";
|
|
278
297
|
```
|
|
279
298
|
|
|
280
|
-
| Export | Kind | Description
|
|
281
|
-
| ------------------ | -------- |
|
|
282
|
-
| `minify` | function | Strips inter-tag whitespace from an XML string
|
|
283
|
-
| `scaffold` | function | Parses an XML string and returns a node tree
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
299
|
+
| Export | Kind | Description |
|
|
300
|
+
| ------------------ | -------- | ------------------------------------------------------- |
|
|
301
|
+
| `minify` | function | Strips inter-tag whitespace from an XML string |
|
|
302
|
+
| `scaffold` | function | Parses an XML string and returns a node tree |
|
|
303
|
+
| `walk` | function | Traverses a node tree depth-first with a visitor |
|
|
304
|
+
| `render` | function | Converts a node tree to an HTML string |
|
|
305
|
+
| `isMalformed` | function | Type guard that narrows `XmlNode` to `MalformedXmlNode` |
|
|
306
|
+
| `XmlNode` | type | The shape of every node in the tree |
|
|
307
|
+
| `XmlNodeRole` | type | Union of all valid role strings |
|
|
308
|
+
| `XmlAttribute` | type | Shape of a parsed attribute `{ name, value }` |
|
|
309
|
+
| `MalformedXmlNode` | type | `XmlNode` narrowed to nodes where `malformed` is `true` |
|
|
290
310
|
|
|
291
311
|
---
|
|
292
312
|
|
package/dist/index.cjs
CHANGED
|
@@ -23,7 +23,8 @@ __export(src_exports, {
|
|
|
23
23
|
isMalformed: () => isMalformed,
|
|
24
24
|
minify: () => minify,
|
|
25
25
|
render: () => render,
|
|
26
|
-
scaffold: () => scaffold
|
|
26
|
+
scaffold: () => scaffold,
|
|
27
|
+
walk: () => walk
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(src_exports);
|
|
29
30
|
|
|
@@ -256,10 +257,19 @@ function extractXmlNodes(xml, position) {
|
|
|
256
257
|
function isMalformed(node) {
|
|
257
258
|
return node.malformed === true;
|
|
258
259
|
}
|
|
260
|
+
|
|
261
|
+
// src/modules/walk/walk.ts
|
|
262
|
+
function walk(nodes, visitor) {
|
|
263
|
+
for (const node of nodes) {
|
|
264
|
+
visitor(node);
|
|
265
|
+
if (node.children) walk(node.children, visitor);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
259
268
|
// Annotate the CommonJS export names for ESM import in node:
|
|
260
269
|
0 && (module.exports = {
|
|
261
270
|
isMalformed,
|
|
262
271
|
minify,
|
|
263
272
|
render,
|
|
264
|
-
scaffold
|
|
273
|
+
scaffold,
|
|
274
|
+
walk
|
|
265
275
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -25,4 +25,6 @@ declare function render(nodes: XmlNode[]): string;
|
|
|
25
25
|
|
|
26
26
|
declare function scaffold(xml: string): XmlNode[];
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
declare function walk(nodes: XmlNode[], visitor: (node: XmlNode) => void): void;
|
|
29
|
+
|
|
30
|
+
export { type MalformedXmlNode, type XmlAttribute, type XmlNode, type XmlNodeRole, isMalformed, minify, render, scaffold, walk };
|
package/dist/index.d.ts
CHANGED
|
@@ -25,4 +25,6 @@ declare function render(nodes: XmlNode[]): string;
|
|
|
25
25
|
|
|
26
26
|
declare function scaffold(xml: string): XmlNode[];
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
declare function walk(nodes: XmlNode[], visitor: (node: XmlNode) => void): void;
|
|
29
|
+
|
|
30
|
+
export { type MalformedXmlNode, type XmlAttribute, type XmlNode, type XmlNodeRole, isMalformed, minify, render, scaffold, walk };
|
package/dist/index.js
CHANGED
|
@@ -227,9 +227,18 @@ function extractXmlNodes(xml, position) {
|
|
|
227
227
|
function isMalformed(node) {
|
|
228
228
|
return node.malformed === true;
|
|
229
229
|
}
|
|
230
|
+
|
|
231
|
+
// src/modules/walk/walk.ts
|
|
232
|
+
function walk(nodes, visitor) {
|
|
233
|
+
for (const node of nodes) {
|
|
234
|
+
visitor(node);
|
|
235
|
+
if (node.children) walk(node.children, visitor);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
230
238
|
export {
|
|
231
239
|
isMalformed,
|
|
232
240
|
minify,
|
|
233
241
|
render,
|
|
234
|
-
scaffold
|
|
242
|
+
scaffold,
|
|
243
|
+
walk
|
|
235
244
|
};
|