Skip to content

Commit 3a79168

Browse files
authored
Merge pull request #49 from NaturalIntelligence/dev
Dev to Master
2 parents b6d3a5e + ecb3910 commit 3a79168

File tree

12 files changed

+60476
-39
lines changed

12 files changed

+60476
-39
lines changed

README.md

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser)
2-
Validate XML or Parse XML to JS/JSON very fast without C/C++ based libraries and no callback
2+
Validate XML or Parse XML to JS/JSON and vise versa rapidly without C/C++ based libraries and no callback
33

44
<p style="color:red;"> **Note**: If you are using v3, your code may start failing in parsing and validation both. I apologize for the breaking changes. But code was supposed to be changed to support large files and many other options. Please refer the code example below for more detail.</p>
55
You can use this library online (press try me button above), or as command from CLI, or in your website, or in npm repo.
@@ -27,6 +27,19 @@ You can use this library online (press try me button above), or as command from
2727
<img src="https://opencollective.com/fast-xml-parser/donate/[email protected]?color=blue" width=300 />
2828
</a>
2929

30+
### Main Features
31+
32+
* Works with node packages, in browser, and in CLI
33+
* Faster than any pure JS implementation.
34+
* It can handle big files (tested up to 100mb).
35+
* You can parse CDATA as separate property.
36+
* You can prefix attributes or group them to separate property. Or can ignore them from result completely.
37+
* You can parse tag's or attribute's value to premitive type: string, integer, float, or boolean. And can optionally decode for HTML char.
38+
* You can remove namespace from tag or attribute name while parsing
39+
* It supports boolean attributes, if configured.
40+
41+
42+
3043
### How to use
3144
**Installation**
3245

@@ -58,7 +71,7 @@ var options = {
5871
//from 3.0.0
5972
var options = {
6073
attributeNamePrefix : "@_",
61-
attrNodeName: false,
74+
attrNodeName: "attr", //default is 'false'
6275
textNodeName : "#text",
6376
ignoreAttributes : true,
6477
ignoreNameSpace : false,
@@ -67,6 +80,8 @@ var options = {
6780
parseAttributeValue : false,
6881
trimValues: true,
6982
decodeHTMLchar: false,
83+
cdataTagName: "__cdata", //default is 'false'
84+
cdataPositionChar: "\\c",
7085
};
7186
if(fastXmlParser.validate(xmlData)=== true){//optional
7287
var jsonObj = fastXmlParser.parse(xmlData,options);
@@ -88,27 +103,63 @@ var jsonObj = fastXmlParser.convertToJson(tObj,options);
88103
* **parseAttributeValue** : Parse the value of an attribute to float, integer, or boolean.
89104
* **trimValues** : trim string values of an attribute or node
90105
* **decodeHTMLchar** : decodes any named and numerical character HTML references excluding CDATA part.
106+
* **cdataTagName** : If specified, parser parse CDATA as nested tag instead of adding it's value to parent tag.
107+
* **cdataPositionChar** : It'll help to covert JSON back to XML without loosing CDATA position.
91108

92109
To use from command line
93110
```bash
94-
$xml2js [-ns|-a|-c] <filename> [-o outputfile.json]
95-
$cat xmlfile.xml | xml2js [-ns|-a|-c] [-o outputfile.json]
111+
$xml2js [-ns|-a|-c|-v|-V] <filename> [-o outputfile.json]
112+
$cat xmlfile.xml | xml2js [-ns|-a|-c|-v|-V] [-o outputfile.json]
96113
```
97114

98-
-ns : To include namespaces (bedefault ignored)
99-
-a : To ignore attributes
100-
-c : To ignore value conversion (i.e. "-3" will not be converted to number -3)
115+
* -ns : To include namespaces (bedefault ignored)
116+
* -a : To ignore attributes
117+
* -c : To ignore value conversion (i.e. "-3" will not be converted to number -3)
118+
* -v : validate before parsing
119+
* -V : only validate
101120

102121
To use it **on webpage**
103122

104-
1. Download and include [parser.js](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/lib/parser.js)
123+
1. Download and include [parser.js] Or use directly from [CDN](https://cdnjs.com/libraries/fast-xml-parser)(https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/lib/parser.js)
105124
```js
106125
var result = parser.validate(xmlData);
107126
if(result !== true) cnosole.log(result.err);
108127
var jsonObj = parser.parse(xmlData);
109128
```
110129

111-
Or use directly from [CDN](https://cdnjs.com/libraries/fast-xml-parser)
130+
## JSON or JS Object to XML
131+
132+
```js
133+
var Parser = require("fast-xml-parser").j2xParser;
134+
//default options need not to set
135+
var defaultOptions = {
136+
attributeNamePrefix : "@_",
137+
attrNodeName: "@", //default is false
138+
textNodeName : "#text",
139+
ignoreAttributes : true,
140+
encodeHTMLchar: false,
141+
cdataTagName: "__cdata", //default is false
142+
cdataPositionChar: "\\c",
143+
format: false,
144+
indentBy: " ",
145+
supressEmptyNode: false
146+
};
147+
var parser = new Parser(defaultOptions);
148+
var xml = parser.parse(json_or_js_obj);
149+
150+
```
151+
**OPTIONS** :
152+
153+
154+
* **attributeNamePrefix** : Identify attributes with this prefix otherwise treat them as a tag.
155+
* **attrNodeName**: Identify attributes when they are grouped under single property.
156+
* **ignoreAttributes** : Don't check for attributes. Treats everything as tag.
157+
* **encodeHTMLchar** : encodes values (except cdata values) when writing to XML.
158+
* **cdataTagName** : If specified, parse matching tag as CDATA
159+
* **cdataPositionChar** : Identify the position where CDATA tag should be placed. If it is blank then CDATA will be added in the last of tag's value.
160+
* **format** : If set to true, then format the XML output.
161+
* **indentBy** : indent by this char `when` format is set to `true`
162+
* **supressEmptyNode** : If set to `true`, tags with no value (text or nested tags) are written as self closing tags.
112163

113164
## Comparision
114165
I decided to created this library when I couldn't find any library which can convert XML data to json without any callback and which is not based on any C/C++ library.
@@ -141,6 +192,14 @@ Installation of such libraries fails on some OS. You may require to install miss
141192

142193
![npm_xml2json_compare](static/img/fxp-validatorv3.png)
143194

195+
#### Benchmark for JSON to XML
196+
197+
| file size | fxp 3.2 js to xml | xml2js 0.4.19 builder |
198+
|------------|-----------------|-----------------|
199+
| 1.3k | 160148.9801 | 10384.99401|
200+
| 1.1m | 173.6374831 | 8.611884025|
201+
202+
![npm_xml2json_compare](static/img/j2x.png)
144203
# Changes from v3
145204

146205
* It can handle big file now (I have tested up to 98mb). Performance report is given above.
@@ -162,11 +221,9 @@ Installation of such libraries fails on some OS. You may require to install miss
162221
* Few validation and parsing bugs are also fixed
163222

164223

165-
Some of my other NPM pojects
166-
- [stubmatic](https://github.com/NaturalIntelligence/Stubmatic) : A stub server to mock behaviour of HTTP(s) / REST / SOAP services. Stubbing redis is on the way.
167-
- [fast-lorem-ipsum](https://github.com/amitguptagwl/fast-lorem-ipsum) : Generate lorem ipsum words, sentences, paragraph very quickly.
224+
### Worth to mention
168225

169-
### TODO
170-
* P2: validating XML stream data
171-
* P2: validator cli
172-
* P2: fast XML prettyfier
226+
- [stubmatic](https://github.com/NaturalIntelligence/Stubmatic) : A stub server to mock behaviour of HTTP(s) / REST / SOAP services.
227+
- **[fastify-xml-body-parser](https://github.com/NaturalIntelligence/fastify-xml-body-parser/)** : Fastify plugin / module to parse XML payload / body into JS object using fast-xml-parser.
228+
- [fast-lorem-ipsum](https://github.com/amitguptagwl/fast-lorem-ipsum) : Generate lorem ipsum words, sentences, paragraph very quickly.
229+
- [Grapes](https://github.com/amitguptagwl/grapes) : Flexible Regular expression engine which can be applied on char stream. (under development)

benchmark/perfTest4.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
var Benchmark = require('benchmark');
2+
var suite = new Benchmark.Suite("XML Parser benchmark");
3+
4+
var Parser = require("../src/j2x");
5+
var parser = new Parser({
6+
format: true,
7+
//supressEmptyNode: true
8+
});
9+
var xml2js = require("xml2js");
10+
var builder = new xml2js.Builder();
11+
//var jsonxml = require('jsontoxml');
12+
13+
var fs = require("fs");
14+
var path = require("path");
15+
var fileNamePath = path.join(__dirname, "../spec/assets/test.json");//1.5k
16+
var jsonData = JSON.parse(fs.readFileSync(fileNamePath).toString());
17+
//xmlData=`<root>${xmlData.repeat(1000)}</root>`;
18+
19+
20+
/* console.log(parser.parse(jsonData));
21+
console.log("----------------")
22+
console.log(builder.buildObject(jsonData));
23+
console.log("----------------")
24+
console.log(jsonxml(jsonData)); */
25+
26+
27+
suite
28+
.add('j2x', function() {
29+
parser.parse(jsonData);
30+
//parser.parse(jsonData,{format:true});
31+
})
32+
.add('xml2js ', function() {
33+
var xml = builder.buildObject(jsonData);
34+
})
35+
/* .add('jsontoxml ', function() {
36+
var xml = jsonxml(jsonData);
37+
}) */
38+
39+
.on('start',function(){
40+
console.log("Running Suite: " + this.name);
41+
})
42+
.on('error',function(e){
43+
console.log("Error in Suite: ",e);
44+
})
45+
.on('abort',function(e){
46+
console.log("Aborting Suite: " + this.name);
47+
})
48+
//.on('cycle',function(event){
49+
// console.log("Suite ID:" + event.target.id);
50+
//})
51+
// add listeners
52+
.on('complete', function() {
53+
for (var j = 0; j < this.length; j++) {
54+
console.log(this[j].name + " : " + this[j].hz + " requests/second");
55+
}
56+
})
57+
// run async
58+
.run({ 'async': true });

cli.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ var path = require('path');
55
var parser = require('./lib/parser');
66
var readToEnd = require('./src/read').readToEnd;
77

8-
98
if(process.argv[2] === "--help" || process.argv[2] === "-h"){
109
console.log("Fast XML Parser " + require(path.join(__dirname + "/package.json")).version);
1110
console.log("----------------");
12-
console.log("xml2js [-ns|-a|-c] <filename> [-o outputfile.json]");
13-
console.log("cat xmlfile.xml | xml2js [-ns|-a|-c] [-o outputfile.json]");
11+
console.log("xml2js [-ns|-a|-c|-v|-V] <filename> [-o outputfile.json]");
12+
console.log("cat xmlfile.xml | xml2js [-ns|-a|-c|-v|-V] [-o outputfile.json]");
13+
console.log("-ns: remove namespace from tag and atrribute name.");
14+
console.log("-a: don't parse attributes.");
15+
console.log("-c: parse values to premitive type.");
16+
console.log("-v: validate before parsing.");
17+
console.log("-V: validate only.");
1418
}else if(process.argv[2] === "--version"){
1519
console.log(require(path.join(__dirname + "/package.json")).version);
1620
}else{
@@ -22,6 +26,8 @@ if(process.argv[2] === "--help" || process.argv[2] === "-h"){
2226
};
2327
var fileName = "";
2428
var outputFileName;
29+
var validate = false;
30+
var validateOnly = false;
2531
for(var i=2; i<process.argv.length;i++){
2632
if(process.argv[i] === "-ns"){
2733
options.ignoreNameSpace = false;
@@ -32,12 +38,28 @@ if(process.argv[2] === "--help" || process.argv[2] === "-h"){
3238
options.parseAttributeValue = false;
3339
}else if(process.argv[i] === "-o"){
3440
outputFileName = process.argv[++i];
41+
}else if(process.argv[i] === "-v"){
42+
validate = true;
43+
}else if(process.argv[i] === "-V"){
44+
validateOnly = true;
3545
}else{//filename
3646
fileName = process.argv[i];
3747
}
3848
}
3949
var callback = function (xmlData) {
40-
output = JSON.stringify(parser.parse(xmlData,options),null,4);
50+
var output = "";
51+
if(validate){
52+
var result = parser.validate(xmlData);
53+
if(result === true){
54+
output = JSON.stringify(parser.parse(xmlData,options),null,4);
55+
}else{
56+
output = result;
57+
}
58+
}else if(validateOnly){
59+
output = parser.validate(xmlData);
60+
}else{
61+
output = JSON.stringify(parser.parse(xmlData,options),null,4);
62+
}
4163
if (outputFileName) {
4264
writeToFile(outputFileName, output);
4365
} else {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fast-xml-parser",
3-
"version": "3.0.1",
3+
"version": "3.2.0",
44
"description": "Validate XML or Parse XML to JS/JSON very fast without C/C++ based libraries",
55
"main": "./src/parser.js",
66
"scripts": {

0 commit comments

Comments
 (0)