From 5260c56f82045286295a50fee4b3459ccb591686 Mon Sep 17 00:00:00 2001 From: Amit Gupta Date: Wed, 17 Nov 2021 07:52:02 +0530 Subject: [PATCH] update README and docs --- docs/CHANGELOG.md => CHANGELOG.md | 18 ++ README.md | 352 +++++++----------------------- USERs.md | 57 +++++ docs/CONTRIBUTING.md | 12 +- docs/imgs/XMLBuilder_v4.png | Bin 0 -> 24994 bytes docs/imgs/XMLParser_large_v4.png | Bin 0 -> 20777 bytes docs/imgs/XMLParser_v4.png | Bin 0 -> 41686 bytes docs/v4/3.XMLBuilder.md | 247 ++++++++++++++++++++- docs/v4/4.XMLValidator.md | 38 ++++ 9 files changed, 432 insertions(+), 292 deletions(-) rename docs/CHANGELOG.md => CHANGELOG.md (93%) create mode 100644 USERs.md create mode 100644 docs/imgs/XMLBuilder_v4.png create mode 100644 docs/imgs/XMLParser_large_v4.png create mode 100644 docs/imgs/XMLParser_v4.png create mode 100644 docs/v4/4.XMLValidator.md diff --git a/docs/CHANGELOG.md b/CHANGELOG.md similarity index 93% rename from docs/CHANGELOG.md rename to CHANGELOG.md index 32a6a2e0..272f01d7 100644 --- a/docs/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library. +**⚠️ 4.0.0-beta.0 / 2021-11-16** +* Name change of many configuration properties. + * `attrNodeName` to `attributesGroupName` + * `attrValueProcessor` to `attributeValueProcessor` + * `parseNodeValue` to `parseTagValue` + * `ignoreNameSpace` to `removeNSPrefix` + * `numParseOptions` to `numberParseOptions` + * spelling correction for `suppressEmptyNode` +* Name change of cli and browser bundle to **fxparser** +* `isArray` option is added to parse a tag into array +* `preserveOrder` option is added to render XML in such a way that the result js Object maintains the order of properties same as in XML. +* Processing behaviour of `tagValueProcessor` and `attributeValueProcessor` are changes with extra input parameters +* j2xparser is renamed to XMLBuilder. +* You need to build XML parser instance for given options first before parsing XML. +* fix #327, #336: throw error when extra text after XML content +* fix #330: attribute value can have '\n', +* fix #350: attrbiutes can be separated by '\n' from tagname + 3.21.1 / 2021-10-31 * Correctly format JSON elements with a text prop but no attribute props ( By [haddadnj](https://github.com/haddadnj) ) diff --git a/README.md b/README.md index 49bab9b8..ddd774d9 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,7 @@ [quality-url]: http://packagequality.com/#?package=fast-xml-parser -Validate XML, Parse XML to JS/JSON and vice versa, or parse XML to Nimn rapidly without C/C++ based libraries and no callback - -To cover expenses, we're planning to launch [FXP Enterprise](https://github.com/NaturalIntelligence/fxp-ent) edition in parallel. Watch it for further updates, if you're interested. - -![Donate $5](static/img/donation_quote.png) +Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback. @@ -26,309 +22,114 @@ To cover expenses, we're planning to launch [FXP Enterprise](https://github.com/ Check [ThankYouBackers](https://github.com/NaturalIntelligence/ThankYouBackers) for our contributors ## Users -List of some applications/projects using Fast XML Parser. (Raise an issue to submit yours) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The list of users is collected either from the list published by Github, cummunicated directly through mails/chat , or from other resources. If you feel that your name in the above list is incorrectly published or you're not the user of this library anymore then you can inform us to remove it. We'll do the necessary changes ASAP. + + + + + + + + + + + + + +Check the list of all known users [here](./USERs.md); + +The list of users is collected either from the list published by Github, cummunicated directly through mails/chat , or from other resources. If you feel that your name in the above list is incorrectly published or you're not the user of this library anymore then you can inform us to remove it. We'll do the necessary changes ASAP. ### Main Features FXP logo * Validate XML data syntactically -* Transform XML to JSON or Nimn -* Transform JSON back to XML +* Parse XML to JS Object +* Build XML from JS Object * Works with node packages, in browser, and in CLI (press try me button above for demo) * Faster than any pure JS implementation. * It can handle big files (tested up to 100mb). -* Various options are available to customize the transformation - * You can parse CDATA as a separate property. - * You can prefix attributes or group them to a separate property. Or they can be ignored from the result completely. - * You can parse tag's or attribute's value to primitive type: string, integer, float, hexadecimal, or boolean. And can optionally decode for HTML char. - * You can remove namespace from tag or attribute name while parsing - * It supports boolean attributes, if configured. +* Controlled parsing using various options ## How to use -### Installation - -To use it as an **NPM package**: +To use as package dependency +`$ npm install fast-xml-parser` +or +`$ yarn add fast-xml-parser` -`npm install fast-xml-parser` - -Or using [yarn](https://yarnpkg.com/): - -`yarn add fast-xml-parser` - -To use it from a **CLI** install it globally with the `-g` option. - -`npm install fast-xml-parser -g` +To use as system command +`$ npm install fast-xml-parser -g` To use it on a **webpage** include it from a [CDN](https://cdnjs.com/libraries/fast-xml-parser) -### XML to JSON - - -```js -const jsonObj = parser.parse(xmlData [,options] ); -``` - -```js -const parser = require('fast-xml-parser'); -const he = require('he'); - -const options = { - attributeNamePrefix : "@_", - attrNodeName: "attr", //default is 'false' - textNodeName : "#text", - ignoreAttributes : true, - ignoreNameSpace : false, - allowBooleanAttributes : false, - parseNodeValue : true, - parseAttributeValue : false, - trimValues: true, - cdataTagName: "__cdata", //default is 'false' - cdataPositionChar: "\\c", - parseTrueNumberOnly: false, - numParseOptions:{ - hex: true, - leadingZeros: true, - //skipLike: /\+[0-9]{10}/ - }, - arrayMode: false, //"strict" - attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a - tagValueProcessor : (val, tagName) => he.decode(val), //default is a=>a - stopNodes: ["parse-me-as-string"], - alwaysCreateTextNode: false -}; - -if( parser.validate(xmlData) === true) { //optional (it'll return an object in case it's not valid) - let jsonObj = parser.parse(xmlData,options); -} - -// Intermediate obj -const tObj = parser.getTraversalObj(xmlData,options); -let jsonObj = parser.convertToJson(tObj,options); - -``` -As you can notice in the above code, validator is not embedded with in the parser and expected to be called separately. However, you can pass `true` or validation options as 3rd parameter to the parser to trigger validator internally. It is same as above example. - -```js -try{ - let jsonObj = parser.parse(xmlData,options, true); -}catch(error){ - console.log(error.message) -} -``` - -Validator returns the following object in case of error; -```js -{ - err: { - code: code, - msg: message, - line: lineNumber, - }, -}; -``` - - -#### Note: [he](https://www.npmjs.com/package/he) library is used in this example - -
- OPTIONS : - -* **attributeNamePrefix** : prepend given string to attribute name for identification -* **attrNodeName**: (Valid name) Group all the attributes as properties of given name. -* **ignoreAttributes** : Ignore attributes to be parsed. -* **ignoreNameSpace** : Remove namespace string from tag and attribute names. -* **allowBooleanAttributes** : a tag can have attributes without any value -* **parseNodeValue** : Parse the value of text node to float, integer, or boolean. -* **parseAttributeValue** : Parse the value of an attribute to float, integer, or boolean. -* **trimValues** : trim string values of an attribute or node -* **decodeHTMLchar** : This options has been removed from 3.3.4. Instead, use tagValueProcessor, and attrValueProcessor. See above example. -* **cdataTagName** : If specified, parser parse CDATA as nested tag instead of adding it's value to parent tag. -* **cdataPositionChar** : It'll help to covert JSON back to XML without losing CDATA position. -* **parseTrueNumberOnly**: if true then values like "+123", or "0123" will not be parsed as number. -* **arrayMode** : When `false`, a tag with single occurrence is parsed as an object but as an array in case of multiple occurences. When `true`, a tag will be parsed as an array always excluding leaf nodes. When `strict`, all the tags will be parsed as array only. When instance of `RegEx`, only tags will be parsed as array that match the regex. When `function` a tag name is passed to the callback that can be checked. -* **tagValueProcessor** : Process tag value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. -* **attrValueProcessor** : Process attribute value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. -* **stopNodes** : an array of tag names which are not required to be parsed. Instead their values are parsed as string. -* **alwaysCreateTextNode** : When `true`, forces the parser always return a property for the `textNodeName` even if there are no attributes or node children. -
- -
- To use from command line - +**Example** +As CLI command ```bash -$xml2js [-ns|-a|-c|-v|-V] [-o outputfile.json] -$cat xmlfile.xml | xml2js [-ns|-a|-c|-v|-V] [-o outputfile.json] +$ fxparser some.xml ``` -* -ns : To include namespaces (by default ignored) -* -a : To ignore attributes -* -c : To ignore value conversion (i.e. "-3" will not be converted to number -3) -* -v : validate before parsing -* -V : only validate -
- - -
- To use it on webpage - +In a node js project ```js -const result = parser.validate(xmlData); -if (result !== true) console.log(result.err); -const jsonObj = parser.parse(xmlData); -``` -
+const { XMLParser, XMLBuilder, XMLValidator} = require("../src/fxp"); -### JSON / JS Object to XML +const parser = new XMLParser(); +let jObj = parser.parse(XMLdata); -```js -const Parser = require("fast-xml-parser").j2xParser; -//default options need not to set -const defaultOptions = { - attributeNamePrefix : "@_", - attrNodeName: "@", //default is false - textNodeName : "#text", - ignoreAttributes : true, - cdataTagName: "__cdata", //default is false - cdataPositionChar: "\\c", - format: false, - indentBy: " ", - supressEmptyNode: false, - tagValueProcessor: a=> he.encode(a, { useNamedReferences: true}),// default is a=>a - attrValueProcessor: a=> he.encode(a, {isAttributeValue: isAttribute, useNamedReferences: true}),// default is a=>a - rootNodeName: "element" -}; -const parser = new Parser(defaultOptions); -const xml = parser.parse(json_or_js_obj); +const builder = new XMLBuilder(); +const xmlContent = builder.build(jObj); ``` -
- OPTIONS : - -With the correct options, you can get the almost original XML without losing any information. - -* **attributeNamePrefix** : Identify attributes with this prefix otherwise treat them as a tag. -* **attrNodeName**: Identify attributes when they are grouped under single property. -* **ignoreAttributes** : Don't check for attributes. Treats everything as tag. -* **encodeHTMLchar** : This option has been removed from 3.3.4. Use tagValueProcessor, and attrValueProcessor instead. See above example. -* **cdataTagName** : If specified, parse matching tag as CDATA -* **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. -* **format** : If set to true, then format the XML output. -* **indentBy** : indent by this char `when` format is set to `true` -* **supressEmptyNode** : If set to `true`, tags with no value (text or nested tags) are written as self closing tags. -* **tagValueProcessor** : Process tag value during transformation. Like HTML encoding, word capitalization, etc. Applicable in case of string only. -* **attrValueProcessor** : Process attribute value during transformation. Like HTML encoding, word capitalization, etc. Applicable in case of string only. -* **rootNodeName** : When input js object is array, parser uses array index by default as tag name. You can set this property for proper response. -
- -## Benchmark - -#### XML to JSON - -![npm_xml2json_compare](static/img/fxpv3-vs-xml2jsv0419_chart.png) - -
- report +In a HTML page +```html + +: + +``` -| file size | fxp 3.0 validator (rps) | fxp 3.0 parser (rps) | xml2js 0.4.19 (rps) | -| ---------- | ----------------------- | ------------------- | ------------------- | -| 1.5k | 16581.06758 | 14032.09323 | 4615.930805 | -| 1.5m | 14918.47793 | 13.23366098 | 5.90682005 | -| 13m | 1.834479235 | 1.135582008 | -1 | -| 1.3k with CDATA | 30583.35319 | 43160.52342 | 8398.556349 | -| 1.3m with CDATA | 27.29266471 | 52.68877009 | 7.966000795 | -| 1.6k with cdata,prolog,doctype | 27690.26082 | 41433.98547 | 7872.399268 | -| 98m | 0.08473858148 | 0.2600104004 | -1 | +### Documents +**v3** +* [documents](./docs/v3/docs.md) -* -1 indicates error or incorrect output. -
+**v4** +1. [GettingStarted.md](./docs/v4/1.GettingStarted.md) +2. [XML Parser](./docs/v4/2.XMLparseOptions.md) +3. [XML Builder](./docs/v4/3.XMLBuilder.md) +4. [XML Validator](./docs/v4/4.XMLValidator.md) +## Performance -#### JSON to XML +### XML Parser -![npm_xml2json_compare](static/img/j2x.png) +![](./docs/imgs/XMLParser_v4.png) -
- report +**Large files** +![](./docs/imgs/XMLParser_large_v4.png) -| file size | fxp 3.2 js to xml | xml2js 0.4.19 builder | -|------------|-----------------|-----------------| -| 1.3k | 160148.9801 | 10384.99401| -| 1.1m | 173.6374831 | 8.611884025| +### XML Builder -
+![](./docs/imgs/XMLBuilder_v4.png) -### Worth to mention +negative means error -- **[BigBit standard)](https://github.com/amitguptagwl/bigbit)** : A standard to represent any number in the universe in comparatively less space and without precision loss. A standard to save memory to represent any text string in comparision of UTF encodings. -- **[imglab](https://github.com/NaturalIntelligence/imglab)** : Speedup and simplify image labeling / annotation. Supports multiple formats, one click annotation, easy interface and much more. There are more than half million images are being annotated every month using this tool. -- [stubmatic](https://github.com/NaturalIntelligence/Stubmatic) : Create fake webservices, DynamoDB or S3 servers, Manage fake/mock stub data, Or fake any HTTP(s) call. -- **[अनुमार्गक (anumargak)](https://github.com/NaturalIntelligence/anumargak)** : The fastest and simple router for node js web frameworks with many unique features. -- [मुनीम (Muneem)](https://github.com/muneem4node/muneem) : A webframework made for all team members. Fast and Featured. -- [शब्दावली (shabdawali)](https://github.com/amitguptagwl/shabdawali) : Amazing human like typing effects beyond your imagination. +## 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)**: Now 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 +* **[Stubmatic](https://github.com/NaturalIntelligence/Stubmatic)** : Create fake webservices, DynamoDB or S3 servers, Manage fake/mock stub data, Or fake any HTTP(s) call. -## Contributors +## Supporters +### Contributors This project exists thanks to [all](graphs/contributors) the people who contribute. [[Contribute](docs/CONTRIBUTING.md)]. @@ -340,16 +141,16 @@ This project exists thanks to [all](graphs/contributors) the people who contribu ### All Contributors --> -## Backers +### Backers Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/fast-xml-parser#backer)] -## Sponsors +### Sponsors -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/fast-xml-parser#sponsor)] +[[Become a sponsor](https://opencollective.com/fast-xml-parser#sponsor)] Support this project by becoming a sponsor. Your logo will show up here with a link to your website. Please also share your detail so we can thankyou on SocialMedia. @@ -363,5 +164,6 @@ Support this project by becoming a sponsor. Your logo will show up here with a l # License - * MIT License + +![Donate $5](static/img/donation_quote.png) \ No newline at end of file diff --git a/USERs.md b/USERs.md new file mode 100644 index 00000000..4cc98083 --- /dev/null +++ b/USERs.md @@ -0,0 +1,57 @@ +Please raise an issue or PR (recommended) to add your name to our User's list + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 18eca346..c42bb143 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -3,8 +3,6 @@ I would like to thank you for your valuable time and effort and applogies if thi This repository is written with the aim of providing high performance not in terms of speed only but comfortability of the user as well. -If your change is not a bug fix please check **nexttodo.md** before implementing any new feature. - ## No rights are resserved Your contribution is valuable. We try to mention your name on README with the avatar. We can't promise to pay you for your contribution. @@ -16,7 +14,7 @@ Here is the check list to publish any change * Changes are well discussed by raising github issue. So they are well known by other contributers and users * Echoing the above point. The purpose / goal for the PR should be mentioned in the description. * Multiple unrelated changes should not be clubbed in single PR. -* Please run perf tests `node benchmark\perfTest3.js` before and after the changes. And mention it in PR description. +* Please run perf tests `$ node benchmark\XmlParser.js` or `$ node benchmark\XmlBuilder.js` before and after the changes. And mention it in PR description. * If you are adding any dependency (specially if it is not the dev dependency) please check that * it is not dependent on other language packages like c/c++ * the package is not very old, very new, discontinued, or has any vulnerability etc. @@ -24,9 +22,9 @@ Here is the check list to publish any change * please check alternate available options * Please write tests for the new changes * Don't forget to write tests for negative cases -* Don't comment existing test case. +* Don't comment existing test cases. -Changes need to do be done by owner +Changes need to do be done by maintainers and should not to be the part of PR by other contributors; * Increase the version number * Update the change log & README if required * Generate the browser bundle @@ -38,10 +36,10 @@ Note that publishing changes or accepting any PR may take time. So please keep p ### Guidelines for first time contributors * https://github.com/Roshanjossey/first-contributions -* **Don't stretch**. If you complete an issue in long time, there is a possibility that other developers finish their part and you face code conflicts which may increase code complexity for you. So it is always good to complete an issue ASAP. +* **Don't stretch**. If you complete an issue in long time, there is a possibility that other developers finish their part first and you face code conflicts which may increase code complexity for you. So it is always good to complete an issue ASAP. * Please refrain to work on multiple issues marked with "first-timers-only" in the same repo. Ask and help your friends and colleagues to attempt rest issues. * Please claim the issue and clear your doubts before raising PR. So other users will not start working on the same issue. * Mention the issue number either in PR detail or in commit message. * Keep increasing the level of challenge. -* Don't hesitate to question on github issue or on twitter. +* Don't hesitate to question on github issue or on stackoverflow. diff --git a/docs/imgs/XMLBuilder_v4.png b/docs/imgs/XMLBuilder_v4.png new file mode 100644 index 0000000000000000000000000000000000000000..d47a8b264d048c995b08119429e2b68bdd5de4d4 GIT binary patch literal 24994 zcmeFZ2{e}dyEc5IXdum|kfK6JiISmIbSD`y&!rF<$~-GdlavNi<{>f`G7nKyNaoB$ z<}vg99alZiyZ`Tc_uk*$-+%A-{nod>XRT)uxBI@X>v#Un^Ei(4IDhvP&dboPV_ruh zk?6>0PAQQ{lw%|k#fLT2_=#RLn>N0zwLGI?MIte5CjO@|3a!Sgc9O`aPAJ>!4z)U2 z*G>hmj5l09*nMdY2ZMQ_)|SoR0;xBjSbultt(`n(aY_%ZZTgSu2qf}qy=x9Bvaoye zvm=^@Psff|=^16!rE7_&k3V}5xW4wonbXy$Uaq3!Q2TVw{Ia2|TX(r%xkxb=^DaFX ziLagKdX^mAjPlJ6i6_r>Pb@i`$voOIz806~&gJR99$!iPI^oOg2M-=}Y@oouw551> zcsK>A=<&V!Itn&?N!ds#hA;XYtL*WmP-+csmE?YVV+Zm2^&Ev%__AHfod#d_dy;N-P2Zcdd3y8^3irJW8+xD;pMfNs1Pyz?8`-Ap!M!r6>oBGM0fY)r2(~qb&NR*E58I*BA)J*HyQu& zF;LPi-+_^o{|nDyf2X%d+qd-sxjV`8{qkIO-)VZd?a^)wK2vdbtycX<^IrRa=coys+n1$uFI54tLwsWk1(saqjHYj=nKw@ z5OJ-~pFhVuI#g6#Tvt^UUQ{Gi5hPM6c5Sx9gWmdAH#u_Uf$hrD46lSloBfDw&Q$-a zP?O%T!6wGW->M>Irdq5j`@JL=FD6G)pV!q5X)(``e#m%{jgmx5Y1l!bF0HEiA}Onf znOt2aP>^uv&K>vbp_Q+ULS0lPLglfLHAT1AQ&uo6I(ESu*d-E*ii#u{qR&=`pY-a!k+qeTHF3PFG{{TfXm1YV zjN5XroAqR$qFj)$Tt=H?yo0*0vYOhfQg%0O-?VFu2fcS3MNGD4+uRTh?sfLIii?Y@ zxoS@7=#3~M=mHKIQRhu}-e%DK zhKoIHJEXqUK_mH1%OWrO)-B4evh!F#*ZG>zz(DLo(Q&F}uI=i;8Nh z={iJjU=@vuh}hL?+iX^%j*!@}!~Og z7e)(`-@Oz5_~FC8Lx*ZI1#1}+Q&JSL3lD{4q^I}S$V;jyDn7xDAO>4|sb&3cwdUBd zFszqEF8K2Gt8fYN8B2@3k`3~1^EFn>GmF)-0th&AczF2yM*-JOV^_>-V--uj9$T0m zu6bwHEM!pfFia%V0{ZeEUU_SzZa(;Z0}FZXsiDG zbnnzm!OBvC$kKeG(OXaD}%TdUVABbDHdvBFn}zQ5_27N~VwYH<5qVbbyQ z=PzCmDX+$h-8FV)v2vyMwMx8o;}yTvlP-$LX5Io?z1dmy+tjoW z9_f<3pViPi!K7#W^<8?mzo5bX>xu_St4?Bh$a8aZqBaB1hHP`T3+N{FhPvq@^yeo+ zR}w~@dyn-@PkgDUP(hh7F)?{K)mm2f`X1t@G@d%(5ZbP zBx`DYr)`dRsMiM8CR5JG#hnVLPI(H}v}u`|#*a^2kQc8r?H+1sZm!@WE8#a;t4J?S z;4+TN_^{QDwB~S;Q;jO?v6zU{@E<=e5xYBkd4BNu|OueW{-e?{FN(L28M=eCn_bA@r1uychBiycR9|q z+D$bSEUU2j$gEwv_N=Vzp$wg0sDa^ufy_vMQo6|^I}<_##AJxv)q7sKA+*Xkg8yM4{3 z&t2)!!9Bi?ixc#wEL5YRU~|8csmf**kb^rWFTNY1W#3Bxf4{O!bobL@fZP%Nfl!mEtr0UfYM1UC``hBO~6udu7}fn%k8X6vDVK#OxCmu5Yoe3K)ICT>e~5x6$a> zr}c`es)j>x{A8?dMMcGYbNh14{rl_4;tMa^0i>jT^vunZ-d$_lNh5^aGhY8 z2oKe=woY4~3tiC|tWUf^Z0;_}<&#MCPl`Lgy)h_7jZ3ralp1bIm)$ELBE-%g*K3|g zFFyI$b!kwq?B|XCjDn@a`eeQ2*;#w=08~Lnx0^t$yf3~1K;?~>u#~VKcGAmq6vlSS z9)8!%IaTiIh6{~(B)|a7UB;ht&Y<*B9f0H1Y?n{y1b-xfJCX{P9g%JyF|)7`*99mu=Al3 zX8gf*x2LCjwQ+;)54dWzXZIsfZONPc@c<7-89N)GQRvc#H3Sd??om2(rekK6Us<#_ zi^%J!s8dK{$lleyT(Uy0i?i+$KLL2pBvDwYq^K}9O0sw$iZ`^n*u{3!hZ{q7QqAKn==dVBMn5QfL>(g!mWf@ik zMw=#ONpIV>&2ed};qdhzr+~E>^Sr&i32p{%WS%oD9334E;Bba!!;Wu=n{CXFJqt2d zuf`GEgO{KG{6uf18g`iNXj>vcG7w#3-_s~Qt#^IETu$?J?Z0D#m+M@a-oO{$WM$+;-0SpEVr$C8q>zRb+bzk&9az2|G+ zUMUj-&5#Q?cpBFxYT4lq$Y$m&*jJfFiJM?}Dp^SXiFr09B}Jm_GTwI2`Iq~^8DnDh zMCvLlM{%6IV+{H%%_l6Z`gD(+l7mAQJ}fFkL04Nl0dlC#7A2C7hqlGfZ)%CT3=J;9n2tZ-?;WA`Ylia~6im zxwzy3`TXeW^43&Qd9I|S^pMG+puGH?L!Pe7WR;9>6cB3Jur2TI-MhnnXN7KSQSbE% z@vmP$bhJSF!U8E?xe~32ANW=n)*zoa*@PUeZ*k)IyjUp!?IRK&60I|ep zw7Y8I{~U-K2gyomYJT9D)^#ds0gs+-`X&GJ$fhxWpq6x*y%TZa;U^+xd?YNA z-Lwbhls0YIQqx0j2737kbUW)$Bk<6|QT@ErbUYx7~w1 zGj=bSZZahzfndHoe0+6an){O*;sLP90~!tdWZ|I1nTr&M-72#jmj;I`7K(xzI%UO6 zXGSLGoKGx76}DOB70mt41jHpuV9hc+ChN5<>auMHCwnDVGzfC+`}C=IdUtSea31~o z*g2=gL+$S!D^k09om$&c`+%RZXv1|?#e-9?b8;4L>0J=5snKIt&|<;@=I7p$KTZFb z#XR$bul4NMMY8zKW60Y2YRr;u6$SY%1;Yj@Z9P4PWTSWalalip_5F!)aoiodnldww zpd?KO0R#`D^~DfX?jiK=-(EoHEyq{Gc)4 zWr1^Qf8u!A=g&{depZ8qduu`zyZ_+9^T0rpa`$69HejQ~<>rd%Z(juQ29#687E>(y z^hp7k0tARXh2LegE$`QyGezEV=*&=~LG5BC>jp2#D&9^1Bci*{C&-IWJtMX~ZZQ^- zgDO@3f=_D_C0PzBj>rPnJB>iq@Se$lR>t2`E{Zz*iXucQumwJyY-I$Su&!PArzZrK zvg!NAfm9opovm50&^pRV1{e+%q+;K^c^8N;DC}=e2}}l9{5&)?`Ps9re7d>c?N|K$ z8C@2~OC1-6GobqraEXA>7I{-IdcFp;Y@9~WVG#>IcI)w*|1P=n&J3#gK>LnApQ}M6 zc^KGg-tdh3f;B#nWub6EMNQ2ViR*P@;`3T7!9I|&xFC!Cqhay`Sq}#0rv?ED_QV;P zEfN?LMS*5=&RK%cEdV|JO1qwLM!$MB81BV(u)byiOe|3=<2;_YucPhr0AaJh7yLS} zzkMqlbo~3Oezf0r#@f}UJ}A4lWp8bD^)74{-lWVQFLTmnoh9mOYhwYwpe3A`ahe$% z7*MjYNk<;>_4Nh%t>C*;U$2S_f;xK^ut|`fCN?=)4Uz>x8aj);g1qRKj;i7IJ1#Mf z{T5+6evH%1B2^IOsjy?`KPl60HsL4frR5q)9PrD3E6kTyt&Oy+cfI_deB1vX+4$cB zE(bd(+PcO+b&dO%g$7|28wL;id5F5qr)62IGBgeTg+T~S+k=Nd8{nvuJwX<))6$ed zVzF7ylF3ze`4gNJ{% zeYqYb8T9jKZ|~sjc-K05`UX_;bo=p3NCNH>$b*p1hFh{OKy$nA?Og}zE@WDt0LX$o z-;{Yh5;z9G4g2i8DgtmmLbJ(IytktrZ4q;tq;3FOb zX5o&U!Ubsrsrj_DH1*>8wQI$KOG=~@HPg?gr>7G;m{9eKz32x)5)@@*WR6>)?1wo2 zBBSQ_Lr|zj#!fdV-5|a+SwrFCn`SepYS#RY*#2M2%4%X2BPWMaD@|rbT7P3DTs9Pt zC+4~1(tMg}XNHG|HS-+Pk^GJe;DQe@QeUQaE%IEenP&WC^XAPDoA@$XB0^Uddz-Rt z;`hjhw8ZC>QqhZrfglE!QLJ0HuG=;z-K35uIwt0!wZN4Z2Qp6Fn6dG&KV`iE@WMt9JhUBR1FBi{$E;N3GH> zeO#9}R`Q-30gT)bTBO z$P|gC#ahQDCi3YINns0bV_-0C$-FLY?-$k5qW!V7G(IKeTPzeE>{}E30e*4WbEGYg zi;L@*y;zAqXXCIfA*Ex%2_UE_z{6AhnBydY)gre8WRjomLH^c8BO~^AJYGCbx!CCG z>G{bpm0Kun^i)A#%lmocc!jJVL8uS}8niFT*-Si0JgzG9V zo^PylCG=J>FyK*c0Re%X?x9dCl;qcl$euX^)#Jj+lOEDOY%XoOE18^i4Gp||_QX`) zP8=T}_x+k{@h`Y!%KT|<2JuiC_cNGLFVFRcs%dEjTUuqOe{;1arvDC$`I=a0CRZy04>#pHqyn#U z#2L}$)^3@tSj?&OpSdkEdTIC6j`o~N2*krrDV-{(mX`wyUKL<#mvimh=Zbur!Zz`C zN6csW!$Jt9XY zKdI>-N>$#g{#Od%EX>j7Pt?uRgoIK5>u1?EXq@JP{-a?$Q$t<4y1GeVy1NViITWLb z9k0#rw}DN}xEAyrEH9z9R@vYk(bZ(!PxaQ*5HdFMq>7_swyxWf%|r^JlV1gX@s0Xf z<~KMHpR5Yh28B>XM<)>)%9p{Zft>aw^TO-vx9?Zb&>xf>dm$SFh0V}+L4vjd)zqN>^so&#__Mp4NMvXR)MsArvhFCP zAmmu0Rq`$Tq<0(BA;UfbhaajGizFo64+yVE+QkR8C8b32mFFy0$Eij@W}ND#ivneX+p?wE}8|ddBmlY#qFeY(5ieR z-8PCMrwTg#&Z0dD?F+IJo(Y>{U%14v&x>PTlC=cHE|pwXRH{rm*r4Z@H;G(EayQPh1$2xm1dLY9fy4eML}_xH73_CH?!+Y9i2qO1Pz!K1$b z+2um2T!15xT|W<`jDe96VSHmRh9ZFnNvMu~Uk9X|{>HXIhtAs%A3jXLdlgO1*WfR} z%F$6#eaG789)XJ+oBM&Jlz6kKC@DptQ;h|`ie@{rq-$=L%D)Ae4rRQ~%v2|u39gHo zM3>cN-Wp6mooI7Zg1?1@9Y1C_qKq!UB?E(W{r8ke{ zI?h)?cFvwZUmrz&N;H25$2yCfGAu%Yz}M+q|F}&$xnZzww~tr^!sIHno$Q`KQ$i&| zuP-~zEqY+Jcd37zn8qkK0g*#lrD=|EjVZp+T- z&zS-hy@m`61m!J3ZhCv=!SduQNuphI$mlC^@wOu^aRjv)Hq|>cKW~-9ctjvi%YxtK zii^{wTWDsG@*|*6a?yRGT}0kUGp^dj#rbkA3!%TeE>DD-LQ$ol$VN{NwJdvKB@(sBxH;t3c0hYm|k)}Iq;CtBSPb0(6v8-hPR5kx_{Ji z@NXdm2#;) zhAUc$1`}ZRA=4rJ;`5r;JSW++XQ3EB6ePcG9u5?DdIwdGV3m=s;eSgcYsZYXfKZ}m zl~PL-DeUx;{TX`Dp3sh$nD5(7t_G$1X`4eRt>5;N(c(uhykvDO@P>3=hNtH$WZT%c zZ>xzPd^SuadS`i}l{-vF@*Z2QCNf6Z>Gfmg8Cs(SEBTOcE`Il?#Y3qX?Ki&y33c4@3cXY}}RtXXj0NK3ucN5o@<(Gf7BYsVHHvl0*hqgd} zK{^p^(3kQ>*6it1r_T5SnS202wuXD?rmdnKYCidGofXxAV8p?>-)w4Y8V z7+U0x-yxd8LFU5pc$wLAZ<+MF2Ap(MFa`TN<>r*)90t?U7A(k>QLUokQo1om((^mpTPFfuYao@ZCl z-W58xq24rvRkD3>I^;C{`t|FZdZ!%gT3cP-Cvyk)6EKXr%>8R2JNzT46i5NSu9K1M zQvv-O=;_ta2@MPkq#W>l80hBWaP8W)<9QjsHJ0h58A)Mb;c1Q3Ho%+Qn12PxO!aCn z3|?~MP0e*-_vh8qSR@31REnUR$;rtLfrm}EqRkY#*uD2e!y{Rxzx0=%0?VvA5Q(^^ zuAS_+JaTJfQb|Q68YPC&v}&o;-${qx4`s(24>%(yM+>wPdqxj|D!97aUT`cd!5Kw?B@=&zDt zuVb}q2?u^RYs=L@t1eK)BBaU)tu+WLgMi=-Xr)H8SmY{}K4PtTAdnvmv>@ky;C-JQ zx*32{w!=-)eSOAI*3UzSRscgZ&-%HYj#ad_Z}^W4>+#+eouJUkx%#H%Uw#F&nI3VC z1P2u~C}FIOkB?7>*8u^3b|8y!^6RnD+6s~OYm>9vwr@9Cnx86Z)iy9Nut6i;6b1Ac+BWZRt9mP^KFW-55fz`T_CLaQ$5 z=_Lb0dov13ff|d@vmiOoF0L6fA|Qf$D4{rS4y-Kt3r1`(`Sh6Mth~I4p9iz3wQ=D= ze=G8tGkvM1atHoaW|$v8P$zZ+?S}tjj=KLq?f=WecP2KAM4J8e$*G6Rs-M^N55h{} zgg*;+@Lz2EyL*L_fE)jJS`2JgZEhD9Kp`g#b|7*@f$C9ZJz{xWAaBw)Yd<-A zG=G7>hYGO9{Hwhl?c<@GAnUx~_N6}TYWDV-G4i2F=$w~<)J%eiZQHuln6RrM9MI9+ zzF$2|Bh_&AB-!`h1TnvxKz$GhmQm*k-UQi#uv2~cV*_j16SsHcvEcK!@7&=5^Xkw; zo2p+(Sl9&AmZ)v$OCAPXV3lxI_YwPb7XX*iQC3!Vs{5%tY#it8T5bFwj3mJQ)CViw z1}I688%>(unSCiQSB8U5+M79=@W;WPx1n#sF^{+c0-C_aW`gFh30lYlb@Aw7QaNJz z+}|JAd1wsWIlDK+=~+lf5-cf8v!#;48I$9MRP@FWYI|-ZAXL45qf z7O+u2^SmilvUr)6uvt?Sv`5pQU!FtG@~gGdP0pJR1P^+J7n7Bs1rTiF<;xx7i(|#U zQAe$MjA77ngl|m9Wn%d53OkVGE~O>nekSZscOF6|lj zmHmi0qC4EyX3plz$tvjzIYtX$p@-wj<;$P?t(h6ZR8>@%rrIE65&hXOU(QD22VCem zqpdwXAZC@2CBnt^(f`RzS$X+0Kuj5Sm#qqfS(g7Dg@)9G#^R8XigSxvE2ORl5#xIQ=`RPpVj|^TFU!5Wo2c5+2aZ*u~c4_TioAY z(%p9O8?|_$JUoUXEtV&bCnhAEgYs8}^-qVoMiw{ihz=>V=xI+Z$rZ?TU|@;sooz!_ z7cdUp`rRpMW(H^k7h9;$G)ZC~+SLHvM8~F1Wgg~(+Q!B>7zhk{a#B-kpvl>`6iAD! zTL5qr?so*v1m1J9nH+P>12M_(Xn6K@at==O3>_1mCt z51(C0bVwW64yw!yBH`L-8+sW>gTG2#l>A!;5ibn--zj;#qjp8oKwdjcIgidIVF1zf zh0MI4U_k%A=#jMYlau`aBH3emN4w)7AMhDdW$^h|FVDZ?>}P48y|bx92Dwn&X?j)p zv(nO1G@wVSKiu2m9momEvOj-eqz0XxDF~fs2Q*j;z>o~QbK8MK5`a00rah8^Z`9lP_4jI=uR22;3nc6Ms!J7>Yc9serSRZ|H@8W?Z- z|1_cWQ&^AQ_^_95q;3v&aM9~OJb~a3U;BQ*n@v1h{?iDIIkLER@E6GX>$0DE>wyWP zn+q2}G|-a27gcRT1N_2dsB7QA$|{Pfk@4UTBOsojpkQCyB;yf>$`sQ(?J?16fwIR7 z#vDXFDz}j0C)z776+!{o{f`RBhs^gibF{3YLi$YQS)81ltMZ)U11bzJ0E%bP5*Z`= zM8Tgz)GadAV2Mhu)iaXa3<(y~VzHeWH zkJU9bz5f1PoliaGIGh>l`kv0){polLqnyJxRSU{P*wW}F7ZuLGx&XPiN0=<$=>S~> zl65s^6=KnAkIT!`0e^W>(@)!HcI_Hr_*B-?iod;{!DM-HPSkleh0URR6XI;uSG0GCT0!bt$h{{K(v_&J6NT}LIOM}tlt_!|B&Qj^rmD^ zo$3p58c~FxNQlV*Z{J%k?c2X!84zwHf5E&W_?Vin(3LM+;a52awTIYLRay!PJJEhn ziC2X+L&X=eO3dC6d#N1T;c9qsdE$&5%7FWYoM$aDU!jDp=h z#V9^NI}WN5fEIs7Ghf`^XAJ*jr>EfCUmAk@s@dh(*RKg~Dp)q`7ZAXWKA?}p{25>C z#o6nCUqBhFCdo?D(sz*Iu2Y!6QKC4?2a_yv0Qyxz_<_pX#%s*SY_BDMJyaU#B+&hr zK_ZqS{|_`cd*;jmdTt2`U0-X=L%5gf=Rp94sD~%?*n0VYZq)S5jQ+*st|(CDt`ya@ zm1!?R2;w9|x~1@0cC=XTs>m~P(pkx@tzk*{tLbv2^luS^x_ejsdQ@6YcsVMBZp8GA z9#ykAbEa};!$kfV{#rPQFYF(>DLq!h$=C~4YuDUw-=^O&=0JHsy}T@&MstkQ>B($^ zubr)Jp!C<;Me*f;QT@E0#_@?f^HGgSxO~D0PZrEw42yx)0fe3p@neA28BiW-Jv8IX zYzIx2r+%UlLIKglseHkrr`rwU!ceMV9;Pttl{LI*1)^xazfDr=9|`7{_)RwIKELi|Ld&@>K3%IkQRRa{7I48 zf$onADGsI+VN^TJQx|id|Zm8ALCeQ0LEwh{X}^ zIruYV{rKwuoxB@%z^K^fJR!#_YJCQ?ON5DT)OF?)u_DC3r$H_qT2Ia=3$j2 zYFKr(5~N37j2s}13G<72!*zyXj0D1{Bpf6MZtn)`8XCA3S4Ud1C@vOA_TIlaQJpi@ zQ>|8?v3I()WNRP2guD?#Lf?iksBt!<9qe4)tH&~%yfU8*Iq{Gm7g=)dv%Jv7qE%fE z$gD&q2J|P3GkCzR5}ZBP69iy~(UnBK0$o&LU&s2AcDI!!sLsyELo0i0;9^O0S+GT} z|GVA6VIZCt+B{s3ZU=nxaDS);5Dc@wI(i))UGDxc;wqoa(3;vV{qaD|->$4-LVTzP zyNM)HtRGuK>?>cmKy+)k_Uxf<9c@ki$3pMhYA%w&2=uCggbUIIZL~yeM_7KouAH14 zv*0C9w6V?EgeQBo$LBU3`MT4xW8%kzHFfA-l4>vgm`C<{IqV?x(#S+N;|?v6QnPl{ zqE~d-x=#Vc3e91OocdKYf3h!s%>Q51|DIiZv33k@Y~ADr?G1$Swx?P{$2b{^5C(Mq z0HD_jR-KoQ!B?p3*w1C9;cMOQGQ*7|8>WiZA03NuY(#_<<_lqktj0!)&&I9=h5jW)O!RtpLV7K44)04-cz4; z`@lA|J1hhK6nTlcD0msH;exyRtNSzI2MKYV@5gl##tKyG7`PCTS*~K-#&NpQC>?3! zxAEk#X?-lrrRb7JZs*gCnx3{L8nfqL9SZy1qNnwcpc7SU( zgs;XFDZ)1jW_#ntw^s;@F8alU22UGvBJ^f~0+I>*WXvMwFE_Puaf^tk!EON6M92gf z2<^l`L4!N^1ygvAodubE4}@ND59B@_bV^kLx-qYHx%R>R`$CsLZLD~Cv?dnbQMRnumpd+adI4iwJ@0zs+qieVZ?Q?!Uua;lb7cI|VUs_VD2|L=^6y2%>Ggs{1e} z=KGMaRNQStv**pZlJ+jQp*-gj0hD|F7X^8F;>LgX7p^C)2&yNqy!<-d;4uLk@&P~h zuvr}n>J3Ot9v^?3J00CaVR|#q?7ZWy30)Tbvq(&YnnLbD)-9A3zu8`1pylnLXFtI& ztW-Ik2cWI@O@cdRMtgKLdCmzkz>39aTXDqedP#RTBmK*y6C*rd_%?oAf1lyQd&6ujH>YdY!2lPqvll>kj zcH!^dZAZ(Y=#w2(;1i}@Ro7h}Wyifk5Jf0jLnnX+B6Kyp=KJ@%=y0aatX-_{F;Ab; z3HW%-^>a$Mz=Pg(OBaXaDW~`Da#ZkVyT81}dbnwuW}@nvBpq$cg!4Rqef1FOIGMbb zv_`KdYGnnM0#9K_p66#jY0y}kLGbgI9z|~}tj^@N%jcgrzBe`oIJ>xL)GTd=Shp$N zYhjOj15LZFtu2WpFE9V;^1-LPc^FA4E-pU#>GaI_I0Y&49khN-2yPyr&}qg+YNOLn zE^B{h)>Plnz(6z~-si`?gZOjm)Npt!m3^^=!fNZm%vaIT?@LQ%)^uDs$aKrY;|UNn z^XkgapHJxOvQg8s?SHnKn!2c}Y7NKU6|*-r(l9GtcmP^fc<}S*+xEx>dZG!jIO?`i43mIm zR|y@&Mf$Os85s;=e5)@lrNLDcAvbpR_1)FYbL>RAKjOA52H!o2hK4457~Y7DTef(> zO9b0Y;pfk5(abo0^(wcnedp?MR^mY`I$fP1oH?`6`&mv_)`)$KYig| zP#}pU>G|o?nFPH8Hg|pzS4;^=J<4rE<5EFM=@zE0q{0<&A^;`j7%sBem@5F&0{S&E za^LfuL`bc#55fxcp*-Nw>EZ4hN7Y9)3jX#2z%qIt!0Qt9Pm=W(wchdo1M7r8OLZbb znJ4}D!q=~A@pYh1r)+EvW0t@ZqpZxU8|AJFF=L%s5zS-M)52N4-nyqxuZ94P$r>4Z zM@MGW2VgTNqLtnk7gK%x`t?p7Wuoc>P&VTJ%gV~SndDRbR<*UY z-TCzoTLQ8Y+9@2fNl6{eR^pchfIY z5b?vbAoGE%IHDlRLbuOM{nYTo-DAI>%XUu+G2-`6R$nB^6F<3pg0XN5@e_@W)c?*) zg2?f85&8LTDgMNxjMW)`@KRGzL*pJSn4Rdd!wKw_ks*Tl29L0?oy9S~Kg;aV?lC^& zYu7#i%7!WII{>qJdEnvo(45p$4e3BB=z@NKa{5u~F}^co@(ESd?L-R^fk^|q!v{#k zJD;C@W7T`UxaY4oq;Oupb=_)M72Pqzzy1n8KmQs!y3?AP%uqiA)AkT+Y2rlNq4hX8 zm`+bm?>o}u7pLi=dvKa+=h(_ApC{g@ww|$2UE{g(=EC~=?IcWtnkk(8{nzg@A6`C`rpZS-zUv8N?V@Uog;hq9 zcGe~JQ*sH6pKFwSkb)J5S+1$K&^Ump+tuh@!;gwFwiHV0}=Mu{g zi2M%A*u-(ww@f#(b|9xJ#3|oVkqVGtSSE5h6LB%(nMWwwDRD2|Jv|X`-Y6<3>A933 zPyWlTWaxhjI}w|Z@Bt(7o^JupUWz$vc6D{Nw6QU(4*b1b!-BVCR!2&EOPxDMi$|nz z;Q|%RayyP#lAuW1qZvZ`_e$JTimRn8FEjr-HQ4Y53ewiCTS?#Kw1baY?SXa1=$r4K z_v=$5T_Raf|KlE(Rj2uLKY4vr_A%f5PwaY9*xcOwSHQGh-^@$g&VM%U{tC?`D*5g4 zxw$*kl66lbPa>f1Ag?kBb8PTGEOx&KIpYJbf!$ZAc$G#>BZtk_cm7x|hq-99RckkaXf)xmR zWYdlv5Ao;kv9(gJ#^=uu@M`BdZlj{6EyP};i$4u-;NzDsAL_X+ZG+d(Lo@LXuoZCn z7^rgb*RSVmg?V_^osHg%ei-(vXKLyp{PKXqugl+?n?)KA^$WW1eURq1;)?yGk4~GV zo!v@}^tO=_On_L<{knom464ekdVwYTdKWdu1r9(;JBN{<`uh3`jQ?o7g~H;D7QaG# zou#dC|D4V8h4Bz5xSMR*4kWG6em zXIbrSX=%|nGxPTK-CS&v?S%os1L$y|QmwzTWzV_7W{U!ExOQ~67D{5|xu|mZC**r6 z6_stON!n{AB_&BjiHAz-j;6l>6fvZs>w5jP`AgBP6@>6uMQX-$@{`Ap zNw=kL!aqVHT{AO#1800B%Y7I!*5Ra`_pp+W4DQu++fF@pSrMUr9Sa6|vZ$nl*b^ku z_&E=uSFtV zy?Qm%bxBlPM+cJWP0+#F*;zmU*|Z9vt}xa3P20Cq$0^^(FJkLVh!0wKn-ZZ3Ow0%c z=<`H}57f#cZ1Ad7BY9FGEL50vrp7~ixZ|jj(B^2#q!S+0owz2Pvf>^T!~)e@Ano&~ zPsdG6cp%wS7WUR zi(&a-o+$=DMfdm79xX9{P*g zMI8r+qr}F-v$;<>3m@W3NjEmMB6{wA5AA?D_yOqGGn7KVqwuDBiarJA$>`HHz0rMJ z%btc^qMl*SN|+YK0QgDnXoO(cf(l+#X>`!A}^yWXGpF^*P%pkh>9|kI);X5 z@pFu`T?9XfU}*>6K+x`#lw?18^k_^y;wX=8fYHc0G$djX z(Y5(hQE?jagxKB4z~I%e<(pm!oLO46=la>cSZo3||1f(8Sru%zQsAENo9AyY{0;kL+5#1ax!n z;x)zZ-%~(fI^sCF56Sc%mI&qc%sxpxa3})1nRP_`u-i}V+N5-f)B#}`yexNPVNmlZ zE!W}Y&s1yhN#6LY<_T|eMjzG8sh&#i{pyO7an8zO`TTG!Z zDBsk~LS_GUAL1wL3}fd$2?)4{tr3pgQ}kg3b|=ogdkvst;3%BUQA*qx`c8q{?v%9j z5A^*=B%*9$mQ+2*Ht}(@rjCv`D(c$g>r(?N*P7qa5tMmxZsMYag%6Z_g4n_hT!hOz z?Q$Yq;rE7oca3Ssjvc5GPXYt)gRFN|N6SXMx{SH_Pi19W^4j6mdyk@@f}vQ7|xo-Nem$A`_e>g5`Z1>1~)Hw!-!4VfHk?IwIF|nyoY-msp5lu1=l8w%)t23fc^2FD7 z*SZd*P@-l^xXj;OW<|BZcG{-1h28pKz);e><@M`=7YH7P0SQ+fFZ?3U|e9VdY0WYT=Or<;q8HeZ5ubbW6*UM9xTuEb?ze`ZP*n;f)%(m zMB8RpA8&6W1wu>Vd{~5(*ojk!PU6@AMLkp}DtPV)wT6^!zhAJJ%DT9zBNc? z2xB=B5m{?%p<0vHvj%*Eui67HnMt$+?FTUbI~#b3nU;arWU;l_LT=4TV;SBAHX@X6Ky99Um`$h zh?6G1)4GpHeShZVMMKawSgaJY!XXmi#_sWlAyp&7PXRJnzEO-*o<#~g0ApTfao~s~ z*wjrQA9`5)Jn@`=AT4ce_3VeAoGJQCUuAgx*MRoovBhU+IM=LQ`yNuSB8JSKm0dm< z`RpFff56x)Ep8j}vuzpf+D*R-t*oplNT3G{(mBZTfg{qE{ncEv^Yant!lns;5Cgkj z)N@4QIIwO9*86~dA?YQ~L=p0RrLeD~w|DOjKi5^&m6h_7niw8IWjbcwp6?C9ebMP8 zuIlmU%Y6;Wp|Q?m9q%8X;r#UF%jV}nqN*+|#Ra$xpT~|-Xs)l#(uU)lzG@r}y>R3| z!#t4+CgE$0xS&%DAVeu|-)@#0XogIO1PY;%^V!mK|7Ne@p`ni9VLqOTu`%~^dx}re zi*xeW+1W9e->4vtINBlUx&wzV>yzKTfy-qaL$F0}ED0nN+cU_p#`?$N4QD*5td z9gHGH@N8DWqhi>5{0N{)uq?DYJggHrSAo9k^n&CfD#7imjEFf8yg=7DuPM< z4W?8)^7X%viNVq7e(ihTi=70-hwP13U)>pU?_ z+=&p~nyId#5sre3PWTqAVm$~fDQ1Nlw;th+J-7R&RkB6Zt_u7{_pS1SfETf zJ3D($27nevASIHlMNEN4?J=Ak=pxT%-7|gh0u?tnu_f@es9r*1;wX>hIXSu0%F0`* zX&HBlRhW@Ymy)=8CU-AMoNFB#pdo2G2IGx5kT{Zaf8D=WrxTx?Tnfl)6PV9t(ilqFZftdkEO&i;N+AW)YHp#jckF<;y_TU3g4*3*DnSQruGbq2NoW0v z@w|PTgP(r`a?8iNn|33&b&QPgM|G33?1eEs=}E%G|PK+GZjN zZF$#|Fl;Ws;XQk|1&Zq7kQ5Zc_8&*P`up#pG~D|_%RU@*XB11ap}L zZO*xyH;QBDfaL;#MwTuYS~T+59Ew;I_L&RtRt&CABUzSYP7MpI4u{5;GlH zWqj&=2+&??YHC%Kt$6WgM`E?`M^aFNuv)O)u8mf@2e<)UQr7q>;0)5}hYufiVxo0l zfz9A{SY5|4mALE35%sMt;&;pYi_HKNX;?(eJt24MI{e(0x?GYtmGffy;(5vHRh-1*3i>4@IAkJUp4+CgPt=%fA?#qed-=K zTETSm1}AXs*kA4hzOd!Wq$z72}SwR}~ z!alwP8Hs@WpmZIhqx2#oB9IgU^OAe4`@T`2M}5SqhnAQ;1&y9vSa{GTxpX&OnP*8S zxfkdpTIs6L=Ugyclk}#2t4p>njpGxwwsu2&3qub$&Ds#gcaV~*L@klj3kD<7091g@ zPo6%dx-CUvYHC__Rusr+&xIYZZgV_8+u70aZBMC~VX0`!su9dk2TL@)47h+#&}9Xpxl+=}uwJiVA1T z`onjX^5t39qzEkrk*N=_I^h0_=FG{HRDjr&PEJnc!N(Y|nQ_wVN4Pjr3@ex;pQPYS zga^OQ)YR03E5((cb$D`ylTp-qA0a#;$w7sVoC?&#X|`3P?jwSONQ#1JDn%-4n7DyM z&En{zDhN?x7=kB?C*0?chMO}CI*V@Ksd(b=zb{)+_T0HuVGC@xocJ)V3WS(u+4j25 z1cwPwpEz-X@6jw(HaQ4_A<#o1;W(B4#KO$%=_0hGAz!fWsl;JJs4+zuy8_p3mm7{e zirJl$;H}V1JrU6QNU{<0%S#I<_dM+cawu`9pn9mpqUn_Ax-`!L;Sv8uDCWTOO)@?# z!t|{o8aH?5+_|mZj3Gy@O8R1mx`%&%sFYm6oSfm^0rz^JjKc`oS&Rz-4c{X8i(Y|i z#Jyw=j+llgdT%bRhJeuq3vKahnlG)>olYoCo8jLE5fRVBNiC7!W~mu7q>y>6F)w=n*p>v`!TyHrXUhD)7Qc1cQCsU zJhTIH-A5Q;6`?7jP66pt;QW(K>89rqn67g_83_E(#>Q5`FHWA>yA-K|1cuGM$=%%d zlD$1h*|-dn?LErffT%<51?-RjmY0_a*aJBpm}wzL`o7j~bUHBIb}mGW3HreIbW;W) zX74I56Dxv35<2H-?!*S12yqL?Nk(Eg2pjOEv$Gh$(W>Ja!(NhKnyUklNZ$gM(gc0(6fMiX@sIB6qLJ^Gi7ss^YK6)`shYDP7yH6N$j@ku* z4MTd!E;|!SPG6$!=)d_mDChxZh+~r>SrO|=YV}OV{JHV<;wTh||5desFYj z{PF3@?uf;!V6cj!?r`Q15&)6(u~b`|AS&R|=6u|`>m(8$s(A?*5+14k!Duc72q6ie z=8WNR==DEQR-|uwaUkR7;`D%7oUgKR+cvIeGXr(&iQ|5&VvVezQF#FyUEGxdSc-k% zE#1krc`YHeU2D&0#Zf{LSNQYt@+ur78UimC-yw)=k&}$5U9;EdVVC=49MW7hAWb>| zv}j0WZ#AzYTi!2&&7q!Vya_4)4Vv(z?3P)~MLo!WpTUPNgB1FZI84QUzOEL>dU}#T z>9!Cx%yfO&U@9=`q3o-BSbul1vc=>g3W#3#E+EcOmuaS#FJEE-dBtK5z3h-)MPhfE z+(c{yAIW7#z&Rj74{d&t`8(xK93mnN7Ws2~h$cH!^$uw4z=4o{8%8&rA_O7`&e$c8 z^I4*wqUX|y7yM~$+{wwwQ5?9h3x5SsoBRg&(puX43L^cN)W1yH3}O?Fstt z@f`2m63`h`k^MW~Pt}XvC86tDu^l)VbnDTRoS8mp-_CYy-W;$# zY61fTqXFoSfXyeLir#LTI`yjjse0g{K${H~e*d2Jc5n8nYuC2zopr06TxS AMgRZ+ literal 0 HcmV?d00001 diff --git a/docs/imgs/XMLParser_large_v4.png b/docs/imgs/XMLParser_large_v4.png new file mode 100644 index 0000000000000000000000000000000000000000..45907c8ca36cfcd33232fe119f879537216f0b67 GIT binary patch literal 20777 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

pxOYsV}PDCMCBb>u8hOjqOU#yKjb^SC$Z=}Ey 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

0Wsp;;}Cr_Wg=k2eF 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 literal 0 HcmV?d00001 diff --git a/docs/v4/3.XMLBuilder.md b/docs/v4/3.XMLBuilder.md index 5b098e78..053f7fb4 100644 --- a/docs/v4/3.XMLBuilder.md +++ b/docs/v4/3.XMLBuilder.md @@ -1,13 +1,240 @@ 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 +```js +const {XMLBuilder} = require('fast-xml-parser'); +const options = { + ignoreAttributes : false +}; + +const builder = new XMLBuilder(options); +let xmlDataStr = builder.build(jObj); +``` + + +## arrayNodeName +When you build XML from an array, it's better to set `arrayNodeName` option to some name. + +```js +const cars = [ + { + "color": "purple", + "type": "minivan", + "registration": "2020-02-03", + "capacity": 7 + }, + { + "color": "orange", + "type": "SUV", + "registration": "2021-05-17", + "capacity": 4 + }, +]; +const builder = new XMLBuilder({ + arrayNodeName: "car" +}); +const output = builder.build(cars); +``` +```xml + + purple + minivan + 2020-02-03 + 7 + + + orange + SUV + 2021-05-17 + 4 + +``` + +## attributeNamePrefix +To recognize attribute properties in the JS object so that they can be trimmed. + +## attributesGroupName +To recognize attribute properties group in the JS object so that they can be trimmed and can form attribute expresstion for a tag. + +## attributeValueProcessor +To customize the bahaviour of parsing an attribute value to the string value. It accepts attribute name and value. + +## cdataTagName +To recognize CDATA properties in a JS object so that they can be transformed correcty. This option is useful only if `preserveOrder: true` + +## format +By default, parsed XML is single line XML string. By `format: true`, you can format it for better view. + +## ignoreAttributes +Don't consider attributes while building XML. Other attributes related properties should be set to correctly identifying an attribute property. + +## indentBy +Applicable only if `format:true` is set. + +## preserveOrder +When you parse a XML using XMLParser with `preserveOrder: true`, the result JS object has different structure. So parse that structure in original XML, you should set the same option while building the XML from that js object. + +## suppressEmptyNode +Tags with no text value would be parsed as empty tags. +Input +```js +const builder = new XMLBuilder({ + arrayNodeName: "any", //not effective + suppressEmptyNode: true +}); +const output = builder.build({ + a: 32, + b: "" +}); +``` +Outout +```xml +32 + +``` + +## tagValueProcessor +To customize the bahaviour of parsing the text value of a tag to the string value. It accepts tag name and value. + +## textNodeName +To recognize text value for a tag in the JS object so that they can be properly assigned to the tag. + +# Restoring original XML + +**Example 1** + +When you use XML Parser with `alwaysCreateTextNode: true`, it doesn't impact XMLBuilder result + +```js + const XMLdata = ` + + purple + minivan + 2020-02-03 + 7 + `; + + const parser = new XMLParser({ + alwaysCreateTextNode: true, + }); + let result = parser.parse(XMLdata); + // console.log(JSON.stringify(result, null,4)); + + const builder = new XMLBuilder({ format: true }); + const output = builder.build(result); +``` +Output +```xml + + purple + minivan + 2020-02-03 + 7 + +``` + +**Example 2** + +When you use XML Parser with `isArray`, it doesn't impact XMLBuilder result under some extent. + + +```js + const XMLdata = ` + + purple + minivan + 2020-02-03 + 7 + `; + + const parser = new XMLParser({ + isArray: (tagName, jPath, isLeafNode, isAttribute) => { + if(isLeafNode) return true; + } + }); + let result = parser.parse(XMLdata); + // console.log(JSON.stringify(result, null,4)); + + const builder = new XMLBuilder(); + const output = builder.build(result); +``` +Output +```xml + + purple + minivan + 2020-02-03 + 7 + +``` + +**Example 3** + +When you use XML Parser with `preserveOrder`, you should use the same option with XMLBuilder. + + +```js + const XMLdata = ` + + purple + minivan + 2020-02-03 + 7 + `; + + const parser = new XMLParser({ + preserveOrder: true + }); + let result = parser.parse(XMLdata); + // console.log(JSON.stringify(result, null,4)); + + const builder = new XMLBuilder({ preserveOrder: true }); + const output = builder.build(result); +``` +Output +```xml + + purple + minivan + 2020-02-03 + 7 + +``` + +**Example 4** + +You should set `attributeNamePrefix` and other properties to the same value for XML Parser and XMLBuilder. + + +```js +const XMLdata = ` + + purple + minivan + 2020-02-03 + 7 +`; + +const options = { + ignoreAttributes: false, + attributeNamePrefix: "@@", + format: true +}; +const parser = new XMLParser(options); +let result = parser.parse(XMLdata); +// console.log(JSON.stringify(result, null,4)); + +const builder = new XMLBuilder(options); +const output = builder.build(result); +``` +Output +```xml + + purple + minivan + 2020-02-03 + 7 + +``` + +[> Next: XmlValidator](./4.XMLValidator.md) \ No newline at end of file diff --git a/docs/v4/4.XMLValidator.md b/docs/v4/4.XMLValidator.md new file mode 100644 index 00000000..ebcf7189 --- /dev/null +++ b/docs/v4/4.XMLValidator.md @@ -0,0 +1,38 @@ +XMLParser uses XMLValidator on demand. + +```js +const {XMLParser} = require("fast-xml-parser"); +try{ + const parser = new XMLParser(options, true); + let result = parser.parse(XMLdata); +}catch(err){ + //: +} +``` + +XML Parser throws error when XML Validator returns error. XML Validator can also be used directly without XML Parser; + +```js +const {XMLValidator} = require("fast-xml-parser"); +const result = XMLValidator.validate(xmlData, { + allowBooleanAttributes: true +}); +``` + +* XMLValidator returns true if no issue is found. +* XMLValidator returns an error object if any issue is found. + +```js +{ + err: { + code: string; + msg: string, + line: number, + col: number + }; +}; +``` + +## Options + +The only option supported by Validator is `allowBooleanAttributes`. You need to set it to `true` when a tag can have boolean attributes. \ No newline at end of file