diff --git a/docs/2.XMLparseOptions.md b/docs/2.XMLparseOptions.md
deleted file mode 100644
index be2561a2..00000000
--- a/docs/2.XMLparseOptions.md
+++ /dev/null
@@ -1,217 +0,0 @@
-We can customize parsing by providing different options to the parser;
-
-```js
-const parser = require('fast-xml-parser');
-
-const options = {
- ignoreAttributes : false
-};
-let jsonObj = parser.parse(xmlDataStr, options);
-```
-
-Let's understand each option in detail with necessary examples
-
-## allowBooleanAttributes
-
-To allow attributes without value.
-
-By default boolean attributes are ignored
-```js
- const xmlData = `wow`;
-
- const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attributeNamePrefix : "@_"
- });
-```
-Output
-```json
-{
- "root": {
- "@_a": "nice",
- "a": "wow"
- }
-}
-```
-Once you allow boolean attributes, they are parsed and set to `true`.
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attributeNamePrefix : "@_",
- allowBooleanAttributes: true
-});
-```
-Output
-```json
-{
- "root": {
- "@_a": "nice",
- "@_checked": true,
- "a": "wow"
- }
-}
-```
-
-## attributeNamePrefix
-
-To recognize attributes in the JS object separately. You can prepend some string with each attribute name.
-
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attributeNamePrefix : "@_"
-});
-```
-Output
-```json
-{
- "root": {
- "@_a": "nice",
- "a": "wow"
- }
-}
-```
-## attrNodeName
-
-To group all the attributes of a tag under given property name.
-
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attrNodeName : "@_"
-});
-```
-Output
-```json
-{
- "root": {
- "@_": {
- "@_a": "nice",
- "@_b": "very nice"
- },
- "a": "wow"
- }
-}
-```
-
-## ignoreAttributes
-
-By default `ignoreAttributes` is set to `true`. It means, attributes are ignored by the parser. If you set any configuration related to attributes without setting `ignoreAttributes: false`, it is useless.
-
-Eg
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- // ignoreAttributes: false,
- attributeNamePrefix : "@_"
-});
-```
-Output
-```json
-{
- "root": {
- "a": "wow"
- }
-}
-```
-
-## ignoreNameSpace
-
-Remove namespace string from tag and attribute names.
-
-Default is `ignoreNameSpace: false`
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attributeNamePrefix : "@_",
- //ignoreNameSpace: true
-});
-```
-Output
-```json
-{
- "root": {
- "@_some:a": "nice",
- "any:a": "wow"
- }
-}
-```
-
-Setting `ignoreNameSpace: true`
-```js
-const xmlData = `wow`;
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- attributeNamePrefix : "@_",
- ignoreNameSpace: true
-});
-```
-Output
-```json
-{
- "root": {
- "@_a": "nice",
- "a": "wow"
- }
-}
-```
-
-## isArray
-
-Whether a single tag should be parsed as array or object can't be decided by FXP. Hence `isArray` method can help users to take the decision if a tag should be parsed as an array.
-
-Eg
-```js
-const xmlData = `
-
- wow
-
- wow again
- unlimited
-
- wow phir se
- `;
-
-const alwaysArray = [
- "root.a.c",
- "root.b"
-];
-
-
-const result = parser.parse(xmlData, {
- ignoreAttributes: false,
- isArray: (tagName, jpath, isLeafNode, isAttribute) => {
- if( alwaysArray.indexOf(jpath) !== -1) return true;
- }
-});
-```
-Output
-```json
-{
- "root": {
- "@_a": "nice",
- "a": [
- "wow",
- {
- "#text": "wow again",
- "c": [
- "unlimited"
- ]
- }
- ],
- "b": [
- "wow phir se"
- ]
- }
-}
-```
\ No newline at end of file
diff --git a/docs/1.GettingStarted.md b/docs/v4/1.GettingStarted.md
similarity index 63%
rename from docs/1.GettingStarted.md
rename to docs/v4/1.GettingStarted.md
index 39e4bd91..11ab7ac9 100644
--- a/docs/1.GettingStarted.md
+++ b/docs/v4/1.GettingStarted.md
@@ -1,6 +1,6 @@
Fast XML Parser is a javascript library to parse XML into JS Object, JSON or to build XML from JS Object without losing any information.
-The aim of this library is to provide fast error free solution to deal with XML in javascript.
+The aim of this library is to provide fast error free solution to deal with XML data format in javascript.
## Setup
@@ -22,11 +22,15 @@ To use it in Browser
This documentation is based on how you can use FXP(fast-xml-parser) in node js.
```js
-const parser = require('fast-xml-parser');
-const fs = require('fs');
-
-const xmlDataStr = fs.readFileSync("./sample.xml").toString();
-let jsonObj = parser.parse(xmlDataStr);
+const {XMLParser, XMLBuilder, XMLValidator} = require('fast-xml-parser');
+
+if(XMLValidator.validate(){
+ const parser = new XMLParser();
+ let jsonObj = parser.parse(xmlData);
+
+ const builder = new XMLBuilder();
+ let samleXmlData = builder.build(jsonObj);
+}
```
-[> Next: Options to parse XML](./2.XMLparseOptions.md)
\ No newline at end of file
+[> Next: XmlParser](./2.XMLparseOptions.md)
\ No newline at end of file
diff --git a/docs/v4/2.XMLparseOptions.md b/docs/v4/2.XMLparseOptions.md
new file mode 100644
index 00000000..60460dc4
--- /dev/null
+++ b/docs/v4/2.XMLparseOptions.md
@@ -0,0 +1,685 @@
+We can customize parsing by providing different options to the parser;
+
+```js
+const {XMLParser} = require('fast-xml-parser');
+
+const options = {
+ ignoreAttributes : false
+};
+
+const parser = new XMLParser(options);
+let jsonObj = parser.parse(xmlDataStr);
+```
+
+Let's understand each option in detail with necessary examples
+
+## allowBooleanAttributes
+
+To allow attributes without value.
+
+By default boolean attributes are ignored
+```js
+ const xmlData = `wow`;
+
+ const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+ };
+ const parser = new XMLParser(options);
+ const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_a": "nice",
+ "a": "wow"
+ }
+}
+```
+Once you allow boolean attributes, they are parsed and set to `true`.
+```js
+const xmlData = `wow`;
+
+const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_",
+ allowBooleanAttributes: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_a": "nice",
+ "@_checked": true,
+ "a": "wow"
+ }
+}
+```
+
+## alwaysCreateTextNode
+
+## attributesGroupName
+
+To group all the attributes of a tag under given property name.
+
+```js
+const xmlData = `wow`;
+
+const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+ attributesGroupName : "@_"
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_": {
+ "@_a": "nice",
+ "@_b": "very nice"
+ },
+ "a": "wow"
+ }
+}
+```
+
+## attributeNamePrefix
+
+To recognize attributes in the JS object separately. You can prepend some string with each attribute name.
+
+```js
+const xmlData = `wow`;
+
+const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_a": "nice",
+ "a": "wow"
+ }
+}
+```
+
+
+
+## attributeValueProcessor
+Similar to `tagValueProcessor` but applied to attributes.
+
+Eg
+```js
+:
+const options = {
+ ignoreAttributes: false,
+ attributeValueProcessor: (name, val, jPath) => {
+ :
+ }
+};
+:
+```
+
+## cdataTagName
+If `cdataTagName` is not set to some property name, then CDATA values are merged to tag's text value.
+
+Eg
+```js
+const xmlData = `
+
+ name:Jack]]>
+ `;
+
+const parser = new XMLParser();
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "a": {
+ "name": "name:JackJack"
+ }
+}
+```
+When `cdataTagName` is set to some property then text value and CDATA are parsed to different properties.
+
+Example 2
+```js
+const options = {
+ cdataTagName: "__cdata"
+}
+```
+Output
+```json
+{
+ "a": {
+ "name": {
+ "__cdata": [
+ "Jack",
+ "Jack"
+ ],
+ "#text": "name:"
+ }
+ }
+}
+```
+
+
+## ignoreAttributes
+
+By default `ignoreAttributes` is set to `true`. It means, attributes are ignored by the parser. If you set any configuration related to attributes without setting `ignoreAttributes: false`, it is useless.
+
+Eg
+```js
+const xmlData = `wow`;
+
+const options = {
+ // ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "a": "wow"
+ }
+}
+```
+
+## isArray
+
+Whether a single tag should be parsed as an array or an object, it can't be decided by FXP. Hence `isArray` method can help users to take the decision if a tag should be parsed as an array.
+
+Eg
+```js
+const xmlData = `
+
+ wow
+
+ wow again
+ unlimited
+
+ wow phir se
+ `;
+
+const alwaysArray = [
+ "root.a.c",
+ "root.b"
+];
+
+
+const options = {
+ ignoreAttributes: false,
+ //name: is either tagname, or attribute name
+ //jPath: upto the tag name
+ isArray: (name, jpath, isLeafNode, isAttribute) => {
+ if( alwaysArray.indexOf(jpath) !== -1) return true;
+ }
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_a": "nice",
+ "a": [
+ "wow",
+ {
+ "#text": "wow again",
+ "c": [
+ "unlimited"
+ ]
+ }
+ ],
+ "b": [
+ "wow phir se"
+ ]
+ }
+}
+```
+
+
+## numberParseOptions
+FXP uses [strnum](https://github.com/NaturalIntelligence/strnum) library to parse string into numbers. This property allows you to set configuration for strnum package.
+
+Eg
+```js
+const xmlData = `
+
+ -0x2f
+ 006
+ 6.00
+ -01.0E2
+ +1212121212
+ `;
+
+const options = {
+ numberParseOptions: {
+ leadingZeros: true,
+ hex: true,
+ skipLike: /\+[0-9]{10}/
+ }
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "a": [ -47, 6, 6, -100, "+1212121212" ],
+ }
+}
+```
+
+
+## parseAttributeValue
+`parseAttributeValue: true` option can be set to parse attributes value. This option uses [strnum](https://github.com/NaturalIntelligence/strnum) package to parse numeric values. For more controlled parsing check `numberParseOptions` option.
+
+Eg
+```js
+const xmlData = `
+
+ wow
+ `;
+
+const options = {
+ ignoreAttributes: false,
+ // parseAttributeValue: true,
+ allowBooleanAttributes: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "a": "wow",
+ "@_a": "nice",
+ "@_checked": true,
+ "@_enabled": "true",
+ "@_int": "34"
+ }
+}
+```
+Boolean attributes are always parsed to `true`. XML Parser doesn't give error if validation is kept off so it'll overwrite the value of repeated attributes.
+
+When `parseAttributeValue: true`
+```json
+{
+ "root": {
+ "a": "wow",
+ "@_a": "nice",
+ "@_checked": true,
+ "@_enabled": true,
+ "@_int": 34
+ }
+}
+```
+
+When validation options are set or `true`.
+```js
+//..
+const output = parser.parse(xmlDataStr, {
+ allowBooleanAttributes: true
+});
+//..
+```
+Output
+```bash
+Error: Attribute 'int' is repeated.:1:48
+```
+
+## parseTagValue
+`parseTagValue: true` option can be set to parse tags value. This option uses [strnum](https://github.com/NaturalIntelligence/strnum) package to parse numeric values. For more controlled parsing check `numberParseOptions` option.
+
+Eg
+```js
+const xmlData = `
+
+ 3534
+ `;
+
+const options = {
+ parseTagValue: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": 35
+}
+```
+
+**Example 2**
+Input
+```xml
+
+ 3534
+
+```
+Output
+```json
+{
+ "root": {
+ "nested": 34,
+ "#text": 35
+ }
+}
+```
+
+**Example 3**
+Input
+```xml
+
+ 353446
+
+```
+Output
+```json
+{
+ "root": {
+ "nested": 34,
+ "#text": "3546"
+ }
+}
+```
+
+
+## removeNSPrefix
+
+Remove namespace string from tag and attribute names.
+
+Default is `removeNSPrefix: false`
+```js
+const xmlData = `wow`;
+
+const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+ //removeNSPrefix: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_some:a": "nice",
+ "any:a": "wow"
+ }
+}
+```
+
+Setting `removeNSPrefix: true`
+```js
+const xmlData = `wow`;
+
+const options = {
+ ignoreAttributes: false,
+ attributeNamePrefix : "@_"
+ removeNSPrefix: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "@_a": "nice",
+ "a": "wow"
+ }
+}
+```
+
+## stopNodes
+
+At particular point, if you don't want to parse a tag and it's nested tags then you can set their path in `stopNodes`.
+
+Eg
+```js
+const xmlData = `
+
+ wow
+
+ wow again
+ unlimited
+
+ wow phir se
+ `;
+
+const options = {
+ stopNodes: ["root.a"]
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "a": [
+ "wow",
+ "\n wow again\n unlimited \n "
+ ],
+ "b": "wow phir se",
+ }
+}
+```
+
+FXP creates text node always when `preserveOrder: true`. Otherwise, it creates a property with the tag name and assign the value directly.
+
+You can force FXP to render a tag with textnode using this option.
+
+Eg
+```js
+const xmlData = `
+
+ wow
+
+ wow again
+ unlimited
+
+ wow phir se
+ `;
+
+const options = {
+ ignoreAttributes: false,
+ // alwaysCreateTextNode: true
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output when `alwaysCreateTextNode: false`
+```json
+{
+ "root": {
+ "a": [
+ "wow",
+ {
+ "c": "unlimited",
+ "#text": "wow again"
+ }
+ ],
+ "b": "wow phir se",
+ "@_a": "nice"
+ }
+}
+```
+Output when `alwaysCreateTextNode: true`
+```json
+{
+ "root": {
+ "a": [
+ {
+ "#text": "wow"
+ },
+ {
+ "c": {
+ "#text": "unlimited"
+ },
+ "#text": "wow again"
+ }
+ ],
+ "b": {
+ "#text": "wow phir se"
+ },
+ "@_a": "nice"
+ }
+}
+```
+
+## tagValueProcessor
+With `tagValueProcessor` you can control how and which tag value should be parsed.
+
+1. If `tagValueProcessor` returns `undefined` or `null` then original value would be set without parsing.
+2. If it returns different value or value with different data type then new value would be set without parsing.
+3. Otherwise original value would be set after parsing (if `parseTagValue: true`)
+4. if tag value is empty then `tagValueProcessor` will not be called.
+
+Eg
+```js
+const xmlData = `
+
+ wow
+
+ wow again
+ unlimited
+
+ wow phir se
+ `;
+
+const options = {
+ ignoreAttributes: false,
+ tagValueProcessor: (tagName, tagValue, jPath, hasAttributes, isLeafNode) => {
+ if(isLeafNode) return tagValue;
+ return "";
+ }
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "a": [
+ {
+ "#text": "wow",
+ "@_a": "2"
+ },
+ {
+ "c": {
+ "#text": "unlimited",
+ "@_a": "2"
+ },
+ "@_a": "2"
+ }
+ ],
+ "b": {
+ "#text": "wow phir se",
+ "@_a": "2"
+ },
+ "@_a": "nice"
+ }
+}
+```
+
+
+## textNodeName
+Text value of a tag is parsed to `#text` property by default. You can always change this.
+
+Eg
+```js
+const xmlData = `
+
+ textalpha
+ `;
+
+const options = {
+ ignoreAttributes: false,
+ textNodeName: "$text"
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "a": {
+ "b": "alpha",
+ "$text": "text"
+ }
+}
+```
+
+## trimValues
+Remove surrounding whitespace from tag or attribute value.
+
+Eg
+```js
+const xmlData = `
+
+ 35 34
+ `;
+
+const options = {
+ ignoreAttributes: false,
+ parseTagValue: true, //default
+ trimValues: false
+};
+const parser = new XMLParser(options);
+const output = parser.parse(xmlDataStr);
+```
+Output
+```json
+{
+ "root": {
+ "nested": 34,
+ "#text": "\n 35 \n ",
+ "@_attri": " ibu te "
+ }
+}
+```
+If the tag value consists whitespaces and `trimValues: false` then value will not be parsed even if `parseTagValue:true`. Similarly, if `trimValues: true` and `parseTagValue:false` then surrounding whitespace will be removed.
+
+```js
+const options = {
+ ignoreAttributes: false,
+ parseTagValue: false,
+ trimValues: true //default
+};
+```
+Output
+```json
+{
+ "root": {
+ "nested": "34",
+ "#text": "35",
+ "@_attri": "ibu te"
+ }
+}
+```
+
+[> Next: XmlBuilder](./3.XMLBuilder.md)
diff --git a/docs/v4/3.XMLBuilder.md b/docs/v4/3.XMLBuilder.md
new file mode 100644
index 00000000..5b098e78
--- /dev/null
+++ b/docs/v4/3.XMLBuilder.md
@@ -0,0 +1,13 @@
+XML Builder can be used to parse a JS object into XML. It supports following options;
+
+* attributeNamePrefix
+* attributesGroupName
+* attributeValueProcessor
+* cdataTagName
+* format
+* ignoreAttributes
+* indentBy
+* suppressEmptyNode
+* tagValueProcessor
+* textNodeName
+