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 +