Skip to content

Commit

Permalink
XML Parser v5
Browse files Browse the repository at this point in the history
  • Loading branch information
amitguptagwl committed Feb 24, 2024
1 parent 364e327 commit ba5f35e
Show file tree
Hide file tree
Showing 30 changed files with 2,183 additions and 17 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.

**4.3.5 / 2024-02-24**
* code for v5 is added for experimental use

**4.3.4 / 2024-01-10**
* fix: Don't escape entities in CDATA sections (#633) (By [wackbyte](https://github.com/wackbyte))

Expand Down
21 changes: 7 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback.

<font size="6">I need a Career advice. I've posted the query on my <a href="github.com/amitguptagwl">profile</a>. Your support would be appreciable.</font>
> XML Parser v5 is added for experimental use
> https://solothought.com
Sponsor this project 👉
<a href="https://github.com/sponsors/NaturalIntelligence">
Expand Down Expand Up @@ -91,6 +92,11 @@ If you want to be an anonymous user of this application and don't want to be hig
* Supports parsing of PI (Processing Instruction) tags with XML declaration tags
* And many more other features.

## v5
I developed v5 in Apr 2023. And I didn't get the chance to complete all the features. I've ensured that new features don't impact performance. With v5, you have more control on parsing output. Check [docs](./docs/v5) for syntax help and basic understanding.

Please leave a comment in discussion forum for your suggestions and if you really need v5.

## How to use

To use as package dependency
Expand Down Expand Up @@ -174,19 +180,6 @@ Check lib folder for different browser bundles

[![](static/img/ni_ads_ads.gif)](https://github.com/NaturalIntelligence/ads/)

## Our other projects and research you must try

* **[BigBit standard](https://github.com/amitguptagwl/bigbit)** :
* Single text encoding to replace UTF-8, UTF-16, UTF-32 and more with less memory.
* Single Numeric datatype alternative of integer, float, double, long, decimal and more without precision loss.
* **[Cytorus](https://github.com/NaturalIntelligence/cytorus)**: Be specific and flexible while running E2E tests.
* Run tests only for a particular User Story
* Run tests for a route or from a route
* Customizable reporting
* Central dashboard for better monitoring
* Options to integrate E2E tests with Jira, Github etc using Central dashboard `Tian`.
* **[Stubmatic](https://github.com/NaturalIntelligence/Stubmatic)** : Create fake webservices, DynamoDB or S3 servers, Manage fake/mock stub data, Or fake any HTTP(s) call.


## Supporters
### Contributors
Expand Down
217 changes: 217 additions & 0 deletions docs/v5/1. Getting Started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@


Example

```js
const options = {
preserveOrder: true,
removeNSPrefix: false, // remove NS from tag name or attribute name if true
stopNodes: [], //nested tags will not be parsed even for errors
htmlEntities: false,
tags:{
unpaired: [],
nameFor:{
cdata: false,
comment: false,
text: '#text'
},
separateTextProperty: false,
//"join" only if preserveOrder: true
valueParsers: ["trim","entities","join","boolean","number","currency","date"]
},
attributes: {
ignore: false,
booleanType:true,
entities: true,
//"groupBy": "att"
},
OutputBuilder: new JsObjOutputBuilder()
};
const parser = new XMLParser(options);
let result = parser.parse(xmlData, true);
```

- You can build your own Output Builder. FXP provides 3 builders
- JsObjOutputBuilder
- JsArrBuilder
- JsMinArrBuilder
- You can control the sequence of value parsing for a tag or attribute
- You can pass a string or bytes array as input.

### Value Parser
You can change the sequence of value parsers or remove one or provide your own parser to control the parsing.

### Output builders
You can use provided output builds or your own output builder.

JsObjOutputBuilder
```js
{
"soap:Envelope": {
"@_xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/",
"soap:Body": {
"rpt:loadReportFileResponseElem": {
"@_xmlns:s": "http://bus.x.com/common/support/v1",
"@_xmlns:rpt": "http://bus.x.com/service/statement/v1",
"s:code": 0,
"s:responseTime": 2588,
"s:responseDbTime": 1893,
"s:requestId": "6b408fd09eb211e7a0807e34820340ec",
"s:route": "172.16.x.x:9192",
"rpt:result": {
"rpt:file": "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <soap:Body>\n <rpt:loadReportFileResponseElem\n xmlns:s=\"http://bus.x.com/common/support/v1\"\n xmlns:rpt=\"http://bus.x.com/service/statement/v1\">\n <s:code>0</s:code>\n <s:responseTime>2588</s:responseTime>\n <s:responseDbTime>1893</s:responseDbTime>\n <s:requestId>6b408fd09eb211e7a0807e34820340ec</s:requestId>\n <s:route>172.16.x.x:9192</s:route>\n <rpt:result>\n <rpt:file></rpt:file>\n </rpt:result>\n </rpt:loadReportFileResponseElem>\n </soap:Body>\n</soap:Envelope>"
}
}
}
}
}
```

JsArrBuilder
```js
{
"tagname": "soap:Envelope",
"child": [
{
"tagname": "soap:Body",
"child": [
{
"tagname": "rpt:loadReportFileResponseElem",
"child": [
{
"tagname": "s:code",
"child": [
{
"#text": 0
}
]
},
{
"tagname": "s:responseTime",
"child": [
{
"#text": 2588
}
]
},
{
"tagname": "s:responseDbTime",
"child": [
{
"#text": 1893
}
]
},
{
"tagname": "s:requestId",
"child": [
{
"#text": "6b408fd09eb211e7a0807e34820340ec"
}
]
},
{
"tagname": "s:route",
"child": [
{
"#text": "172.16.x.x:9192"
}
]
},
{
"tagname": "rpt:result",
"child": [
{
"tagname": "rpt:file",
"child": [
{
"#text": "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <soap:Body>\n <rpt:loadReportFileResponseElem\n xmlns:s=\"http://bus.x.com/common/support/v1\"\n xmlns:rpt=\"http://bus.x.com/service/statement/v1\">\n <s:code>0</s:code>\n <s:responseTime>2588</s:responseTime>\n <s:responseDbTime>1893</s:responseDbTime>\n <s:requestId>6b408fd09eb211e7a0807e34820340ec</s:requestId>\n <s:route>172.16.x.x:9192</s:route>\n <rpt:result>\n <rpt:file></rpt:file>\n </rpt:result>\n </rpt:loadReportFileResponseElem>\n </soap:Body>\n</soap:Envelope>"
}
]
}
]
}
],
":@": {
"@_xmlns:s": "http://bus.x.com/common/support/v1",
"@_xmlns:rpt": "http://bus.x.com/service/statement/v1"
}
}
]
}
],
":@": {
"@_xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/"
}
}
```

JsMinArrBuilder
```js
{
"soap:Envelope": [
{
"soap:Body": [
{
"rpt:loadReportFileResponseElem": [
{
"s:code": [
{
"#text": 0
}
]
},
{
"s:responseTime": [
{
"#text": 2588
}
]
},
{
"s:responseDbTime": [
{
"#text": 1893
}
]
},
{
"s:requestId": [
{
"#text": "6b408fd09eb211e7a0807e34820340ec"
}
]
},
{
"s:route": [
{
"#text": "172.16.x.x:9192"
}
]
},
{
"rpt:result": [
{
"rpt:file": [
{
"#text": "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <soap:Body>\n <rpt:loadReportFileResponseElem\n xmlns:s=\"http://bus.x.com/common/support/v1\"\n xmlns:rpt=\"http://bus.x.com/service/statement/v1\">\n <s:code>0</s:code>\n <s:responseTime>2588</s:responseTime>\n <s:responseDbTime>1893</s:responseDbTime>\n <s:requestId>6b408fd09eb211e7a0807e34820340ec</s:requestId>\n <s:route>172.16.x.x:9192</s:route>\n <rpt:result>\n <rpt:file></rpt:file>\n </rpt:result>\n </rpt:loadReportFileResponseElem>\n </soap:Body>\n</soap:Envelope>"
}
]
}
]
}
],
":@": {
"@_xmlns:s": "http://bus.x.com/common/support/v1",
"@_xmlns:rpt": "http://bus.x.com/service/statement/v1"
}
}
]
}
],
":@": {
"@_xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/"
}
}
```

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fast-xml-parser",
"version": "4.3.4",
"version": "4.3.5",
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
"main": "./src/fxp.js",
"scripts": {
Expand Down
32 changes: 32 additions & 0 deletions spec/v5/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const XMLParser = require("../../src/v5/XMLParser");
const JsObjOutputBuilder = require("../../src/v5/OutputBuilders/JsObjBuilder");
const JsArrBuilder = require("../../src/v5/OutputBuilders/JsArrBuilder");
const JsMinArrBuilder = require("../../src/v5/OutputBuilders/JsMinArrBuilder");

const fs = require("fs");
const path = require("path");
const fileNamePath = path.join(__dirname, "../assets/ptest.xml");//with CDATA
// const fileNamePath = path.join(__dirname, "../assets/ptest_with_prolog.xml");//with CDATA
// const fileNamePath = path.join(__dirname, "../assets/sample.xml");//1.5k
// const fileNamePath = path.join(__dirname, "../assets/midsize.xml");//13m
// const fileNamePath = path.join(__dirname, "../assets/large.xml");//98m
const xmlData = fs.readFileSync(fileNamePath).toString();

describe("XMLParser Entities", function() {

it("should parse", function() {

const options = {
attributes: {
ignore: false,
booleanType:true
},
OutputBuilder: new JsMinArrBuilder()
};
const parser = new XMLParser(options);
let result = parser.parse(xmlData);

console.log(JSON.stringify(result,null,4));
// expect(result).toEqual(expected);
});
});
16 changes: 16 additions & 0 deletions src/v5/CharsSymbol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
modules.export = {
"<" : "<", //tag start
">" : ">", //tag end
"/" : "/", //close tag
"!" : "!", //comment or docttype
"!--" : "!--", //comment
"-->" : "-->", //comment end
"?" : "?", //pi
"?>" : "?>", //pi end
"?xml" : "?xml", //pi end
"![" : "![", //cdata
"]]>" : "]]>", //cdata end
"[" : "[",
"-" : "-",
"D" : "D",
}
Loading

0 comments on commit ba5f35e

Please sign in to comment.