@lowlighter/xml 5.3.1 → 5.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 +212 -0
- package/_types.ts +2 -2
- package/deno.jsonc +3 -2
- package/mod.mjs +1 -1
- package/package.json +4 -2
- package/parse.mjs +1 -1
- package/stringify.mjs +1 -1
- package/stringify.ts +29 -6
- package/stringify_test.ts +25 -8
- package/wasm_xml_parser/wasm_xml_parser.js +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,218 @@
|
|
|
21
21
|
- Custom `reviver` and `replacer` functions
|
|
22
22
|
- Metadata stored into non-enumerable properties for advanced usage
|
|
23
23
|
|
|
24
|
+
## 🕊️ Migrating from `4.x.x` to `5.x.x`
|
|
25
|
+
|
|
26
|
+
Starting from version `5.0.0`, this library use a WASM-compiled binding of the [quick-xml](https://github.com/tafia/quick-xml) rust package. It provides better performances while allowing to support more features.
|
|
27
|
+
|
|
28
|
+
### Internal API changes
|
|
29
|
+
|
|
30
|
+
The `$XML` internal symbol has been replaced by a set of non-enumerable properties:
|
|
31
|
+
|
|
32
|
+
- Parent node can now be accessed through `"~parent"` property (it'll be `null` for the XML document node)
|
|
33
|
+
- Tag name can now be accessed through `"~name"` property
|
|
34
|
+
- Children nodes can now be accessed through `"~children"` property
|
|
35
|
+
- CDATA can now be tested by checking whether a node has a `"~name": "~cdata"` (if flattened, you'll need to check from the parent node using `~children` property)
|
|
36
|
+
|
|
37
|
+
```xml
|
|
38
|
+
<root>
|
|
39
|
+
<node><![CDATA[hello <world>]]></node>
|
|
40
|
+
</root>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```diff
|
|
44
|
+
<ref *1> {
|
|
45
|
+
- [$XML]: { cdata: [ "root", "node" ] },
|
|
46
|
+
+ "~parent": null,
|
|
47
|
+
+ "~name": "~xml",
|
|
48
|
+
root: {
|
|
49
|
+
node: "hello <world>",
|
|
50
|
+
- [$XML]: { name: "root", parent: null },
|
|
51
|
+
+ "~parent": [Circular *1],
|
|
52
|
+
+ "~name": "root",
|
|
53
|
+
+ "~children": [ { "~name": "~cdata", "#text": "hello <world>" } ],
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### XML document changes
|
|
59
|
+
|
|
60
|
+
XML document properties have been moved directly to top-level rather than being stored in `xml` property.
|
|
61
|
+
|
|
62
|
+
Doctype is now stored in `"#doctype"` property, and attributes values are set to `""` rather than `true`.
|
|
63
|
+
|
|
64
|
+
Processing instructions (like XML stylesheets) are now parsed the same way as regular nodes but have been moved into `"#instructions"` property.
|
|
65
|
+
|
|
66
|
+
```xml
|
|
67
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
68
|
+
<?xml-stylesheet href="styles.xsl" type="text/xsl"?>
|
|
69
|
+
<!DOCTYPE attribute>
|
|
70
|
+
<root/>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```diff
|
|
74
|
+
{
|
|
75
|
+
- xml: {
|
|
76
|
+
- "@version": "1.0",
|
|
77
|
+
- "@encoding": "UTF-8",
|
|
78
|
+
- },
|
|
79
|
+
- "$stylesheets": [ { "@href": "styles.xsl", "@type": "text/xsl" } ]
|
|
80
|
+
- doctype: { "@attribute": true },
|
|
81
|
+
+ "@version": "1.0",
|
|
82
|
+
+ "@encoding": "UTF-8",
|
|
83
|
+
+ "#instructions": {
|
|
84
|
+
+ "xml-stylesheet": { "@href": "styles.xsl", "@type": "text/xsl" }
|
|
85
|
+
+ },
|
|
86
|
+
+ "#doctype": { "@attribute": "" },
|
|
87
|
+
root: null
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Mixed content support
|
|
92
|
+
|
|
93
|
+
This breaks any existing code that was expecting mixed content to always be a string. Now mixed content nodes will be parsed as usual, and the `#text` property will contain the "inner text" of the node.
|
|
94
|
+
|
|
95
|
+
Note that `#text` is actually a getter that recursively gets the `#text` of children nodes (ignoring comment nodes) so it'll return the inner text regardless of the node depth.
|
|
96
|
+
|
|
97
|
+
```xml
|
|
98
|
+
<root>some <b>bold</b> text</root>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```diff
|
|
102
|
+
{
|
|
103
|
+
- root: "some <b>bold</b> text",
|
|
104
|
+
+ root: {
|
|
105
|
+
+ "#text": "some bold text",
|
|
106
|
+
+ b: "bold",
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Comments
|
|
111
|
+
|
|
112
|
+
Comments have been moved into `"#comments"` property. Note that this property is now always an array, even if there is only one comment.
|
|
113
|
+
|
|
114
|
+
Additionally, you can find comments into the `~children` property by searching for nodes with `"~name": "~comment"`. If you call the `#text` getter on a parent node containing comments, it will return the inner text without comments.
|
|
115
|
+
|
|
116
|
+
```xml
|
|
117
|
+
<root><!--some comment--></root>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```diff
|
|
121
|
+
{
|
|
122
|
+
root: {
|
|
123
|
+
- "#comment": "some comment",
|
|
124
|
+
+ "#comments": [ "some comment" ],
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Parsing
|
|
130
|
+
|
|
131
|
+
#### Options
|
|
132
|
+
|
|
133
|
+
Parse options are categorized into 4 groups:
|
|
134
|
+
|
|
135
|
+
- `clean`, which can remove `attributes`, `comments`, xml `doctype` and `instructions` from the output
|
|
136
|
+
- `flatten`, which can flatten nodes with only a `text` node, `empty` ones or transform `attributes` only nodes into objects without the `@` prefix
|
|
137
|
+
- `revive`, which can `trim` content (unless `xml:space="preserve"`), unescape xml `entities`, revive `booleans` and `numbers`
|
|
138
|
+
- You can also provide a `custom` reviver function (applied after other revivals) that will be called on each attribute and node
|
|
139
|
+
- _Note that signature of the reviver function has changed_
|
|
140
|
+
- `mode`, which can be either `xml` or `html`. Choosing the latter will be more permissive than the former.
|
|
141
|
+
|
|
142
|
+
```diff
|
|
143
|
+
const options = {
|
|
144
|
+
- reviveBooleans: true,
|
|
145
|
+
- reviveNumbers: true,
|
|
146
|
+
- reviver:() => {},
|
|
147
|
+
+ revive: { booleans: true, numbers: true, custom: () => {} },
|
|
148
|
+
- emptyToNull: true,
|
|
149
|
+
- flatten: true,
|
|
150
|
+
+ flatten: { text: true, empty: true },
|
|
151
|
+
- debug: false,
|
|
152
|
+
- progress: () => null,
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Please refer to the [documentation](https://jsr.io/@libs/xml/doc) for more information.
|
|
157
|
+
|
|
158
|
+
#### Parsing streams
|
|
159
|
+
|
|
160
|
+
The `parse()` function supports any `ReaderSync` interface, which means you can pass directly a file reader for example.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { parse } from "./parse.ts"
|
|
164
|
+
parse(await Deno.readTextFile("example.xml"))
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Stringifying
|
|
168
|
+
|
|
169
|
+
#### Options
|
|
170
|
+
|
|
171
|
+
Stringify options are now categorized into 2 groups:
|
|
172
|
+
|
|
173
|
+
- `format`, which can configure the `indent` string and automatically `breakline` when a text node is too long
|
|
174
|
+
- `replace`, which can forcefully escape xml `entities`
|
|
175
|
+
- You can also provide a `custom` replacer function that will be called on each attribute and node
|
|
176
|
+
- Note that signature of the replacer function has changed
|
|
177
|
+
|
|
178
|
+
```diff
|
|
179
|
+
const options = {
|
|
180
|
+
- indentSize: 2,
|
|
181
|
+
+ format: { indent: " " },
|
|
182
|
+
- escapeAllEntities: true,
|
|
183
|
+
- replacer: () => {},
|
|
184
|
+
+ replace: { entities: true, custom: () => {} },
|
|
185
|
+
- nullToEmpty: false,
|
|
186
|
+
- debug: false,
|
|
187
|
+
- progress: () => null,
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Please refer to the [documentation](https://jsr.io/@libs/xml/doc) for more information.
|
|
192
|
+
|
|
193
|
+
### Stringifying content
|
|
194
|
+
|
|
195
|
+
Please refer to the above section about API changes. If you were handling XML properties, using the `$XML` symbol or `#comment`, you'll most likely need to update your code.
|
|
196
|
+
|
|
197
|
+
The library now provides `comment()` and `cdata()` helpers to respectively create comment and CDATA nodes.
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { cdata, comment, stringify } from "./stringify.ts"
|
|
201
|
+
stringify({
|
|
202
|
+
"@version": "1.0",
|
|
203
|
+
"@encoding": "UTF-8",
|
|
204
|
+
root: {
|
|
205
|
+
comment: comment("hello world"),
|
|
206
|
+
cdata: cdata("bonjour <le monde>"),
|
|
207
|
+
text: "hello world",
|
|
208
|
+
node: {
|
|
209
|
+
foo: true,
|
|
210
|
+
bar: 42,
|
|
211
|
+
baz: {
|
|
212
|
+
"@attribute": "value",
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
```xml
|
|
220
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
221
|
+
<root>
|
|
222
|
+
<comment><!--hello world--></comment>
|
|
223
|
+
<cdata><![CDATA[bonjour <le monde>]]></cdata>
|
|
224
|
+
<text>hello world</text>
|
|
225
|
+
<node>
|
|
226
|
+
<foo>true</foo>
|
|
227
|
+
<bar>42</bar>
|
|
228
|
+
<baz attribute="value"/>
|
|
229
|
+
</node>
|
|
230
|
+
</root>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Note that also you can theorethically use internal properties we strongly advise against it currently. Supporting `~children` might be added in the future ([#57](https://github.com/lowlighter/libs/issues/57)) for mixed content support, but its behavior is not defined yet. Setting
|
|
234
|
+
`~name` manually might lead to unexpected behaviors.
|
|
235
|
+
|
|
24
236
|
## 📜 License and credits
|
|
25
237
|
|
|
26
238
|
```
|
package/_types.ts
CHANGED
|
@@ -25,11 +25,11 @@ export type xml_node = {
|
|
|
25
25
|
/** XML document. */
|
|
26
26
|
export type xml_document = xml_node & {
|
|
27
27
|
/** XML version. */
|
|
28
|
-
["@version"]?:
|
|
28
|
+
["@version"]?: string
|
|
29
29
|
/** XML character encoding. */
|
|
30
30
|
["@encoding"]?: string
|
|
31
31
|
/** XML standalone. */
|
|
32
|
-
["@standalone"]?:
|
|
32
|
+
["@standalone"]?: string
|
|
33
33
|
/** XML doctype. */
|
|
34
34
|
["#doctype"]?: xml_node
|
|
35
35
|
/** XML instructions. */
|
package/deno.jsonc
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"icon": "📃",
|
|
3
3
|
"name": "@libs/xml",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.4.0",
|
|
5
5
|
"description": "XML parser/stringifier with no dependencies.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"xml",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"stringifier",
|
|
10
10
|
"esm"
|
|
11
11
|
],
|
|
12
|
-
"license": "MIT
|
|
12
|
+
"license": "MIT",
|
|
13
13
|
"author": "lowlighter (Simon Lecoq)",
|
|
14
14
|
"funding": "https://github.com/sponsors/lowlighter",
|
|
15
15
|
"homepage": "https://github.com/lowlighter/libs",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"url": "git+https://github.com/lowlighter/libs.git"
|
|
27
27
|
},
|
|
28
28
|
"npm": true,
|
|
29
|
+
"deno.land/x": true,
|
|
29
30
|
"exports": {
|
|
30
31
|
".": "./mod.ts",
|
|
31
32
|
"./parse": "./parse.ts",
|