arraybuffer-xml-parser
Advanced tools
Comparing version 0.1.0 to 0.2.0
107
lib/index.js
@@ -16,13 +16,12 @@ 'use strict'; | ||
const defaultOptions = { | ||
trimValues: true, | ||
attributeNamePrefix: '@_', | ||
attributesNodeName: false, | ||
textNodeName: '#text', | ||
trimValues: true, | ||
ignoreAttributes: false, | ||
ignoreNameSpace: false, | ||
allowBooleanAttributes: false, | ||
dynamicTypingAttributeValue: true, | ||
allowBooleanAttributes: false, | ||
textNodeName: '#text', | ||
dynamicTypingNodeValue: true, | ||
@@ -39,15 +38,16 @@ arrayMode: false, | ||
class XMLNode { | ||
constructor(tagName, parent, val) { | ||
constructor(tagName, parent, value) { | ||
this.tagName = tagName; | ||
this.parent = parent; | ||
this.child = {}; //child tags | ||
this.attrsMap = {}; //attributes map | ||
this.val = val; //text only | ||
this.children = Object.create({}); //child tags | ||
this.attributes = Object.create({}); //attributes map | ||
this.value = value; //text only | ||
this.startIndex = -1; | ||
} | ||
addChild(child) { | ||
if (Array.isArray(this.child[child.tagName])) { | ||
if (Array.isArray(this.children[child.tagName])) { | ||
//already presents | ||
this.child[child.tagName].push(child); | ||
this.children[child.tagName].push(child); | ||
} else { | ||
this.child[child.tagName] = [child]; | ||
this.children[child.tagName] = [child]; | ||
} | ||
@@ -220,7 +220,7 @@ } | ||
function stringParseValue(val, shouldParse) { | ||
if (shouldParse && typeof val === 'string') { | ||
return dynamicTyping.parseString(val); | ||
function stringParseValue(value, shouldParse) { | ||
if (shouldParse && typeof value === 'string') { | ||
return dynamicTyping.parseString(value); | ||
} else { | ||
return val === undefined ? '' : val; | ||
return value === undefined ? '' : value; | ||
} | ||
@@ -278,6 +278,6 @@ } | ||
: xmlData.subarray(dataIndex, dataIndex + dataSize); | ||
if (currentNode.val === undefined) { | ||
currentNode.val = value; | ||
if (currentNode.value === undefined) { | ||
currentNode.value = value; | ||
} else { | ||
currentNode.val = concat(currentNode.val, value); | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
@@ -289,7 +289,7 @@ } | ||
) { | ||
currentNode.child = []; | ||
if (currentNode.attrsMap === undefined) { | ||
currentNode.attrsMap = {}; | ||
currentNode.children = []; | ||
if (currentNode.attributes === undefined) { | ||
currentNode.attributes = {}; | ||
} | ||
currentNode.val = xmlData.subarray(currentNode.startIndex + 1, i); | ||
currentNode.value = xmlData.subarray(currentNode.startIndex + 1, i); | ||
} | ||
@@ -317,4 +317,4 @@ currentNode = currentNode.parent; | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.val = concat( | ||
currentNode.val, | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
@@ -362,3 +362,3 @@ ? arrayTrim(xmlData.subarray(dataIndex, dataSize + dataIndex)) | ||
currentNode.val = concat(currentNode.val, value); | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
@@ -376,6 +376,6 @@ | ||
if (tagExp) { | ||
childNode.val = tagExp; | ||
childNode.value = tagExp; | ||
} | ||
} else { | ||
currentNode.val = concat(currentNode.val, tagExp); | ||
currentNode.value = concat(currentNode.value, tagExp); | ||
} | ||
@@ -411,4 +411,4 @@ | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.val = concat( | ||
currentNode.val, | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
@@ -434,3 +434,6 @@ ? arrayTrim(xmlData.subarray(dataIndex, dataIndex + dataSize)) | ||
if (tagAttributes) { | ||
childNode.attrsMap = parseAttributesString(tagAttributes, options); | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
@@ -449,3 +452,6 @@ currentNode.addChild(childNode); | ||
if (tagAttributes && shouldBuildAttributesMap) { | ||
childNode.attrsMap = parseAttributesString(tagAttributes, options); | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
@@ -495,2 +501,9 @@ currentNode.addChild(childNode); | ||
/** | ||
* | ||
* @param {*} node | ||
* @param {*} options | ||
* @param {*} parentTagName | ||
* @returns | ||
*/ | ||
function traversableToJSON(node, options, parentTagName) { | ||
@@ -501,17 +514,17 @@ const { dynamicTypingNodeValue, tagValueProcessor, arrayMode } = options; | ||
if (tagValueProcessor) { | ||
node.val = node.val && tagValueProcessor(node.val, node); | ||
node.value = node.value && tagValueProcessor(node.value, node); | ||
} | ||
if (typeof node.val === 'string' && dynamicTypingNodeValue) { | ||
node.val = dynamicTyping.parseString(node.val); | ||
if (typeof node.value === 'string' && dynamicTypingNodeValue) { | ||
node.value = dynamicTyping.parseString(node.value); | ||
} | ||
// when no child node or attr is present | ||
if ( | ||
(!node.child || isEmptyObject(node.child)) && | ||
(!node.attrsMap || isEmptyObject(node.attrsMap)) | ||
(!node.children || isEmptyObject(node.children)) && | ||
(!node.attributes || isEmptyObject(node.attributes)) | ||
) { | ||
return node.val === undefined ? '' : node.val; | ||
return node.value === undefined ? '' : node.value; | ||
} | ||
// otherwise create a textnode if node has some text | ||
if (node.val !== undefined && node.val.length !== 0) { | ||
if (node.value !== undefined && node.value.length !== 0) { | ||
const asArray = isTagNameInArrayMode( | ||
@@ -523,16 +536,16 @@ node.tagName, | ||
result[options.textNodeName] = asArray ? [node.val] : node.val; | ||
result[options.textNodeName] = asArray ? [node.value] : node.value; | ||
} | ||
merge(result, node.attrsMap, arrayMode); | ||
merge(result, node.attributes, arrayMode); | ||
const keys = Object.keys(node.child); | ||
const keys = Object.keys(node.children); | ||
for (let index = 0; index < keys.length; index++) { | ||
const tagName = keys[index]; | ||
if (node.child[tagName] && node.child[tagName].length > 1) { | ||
if (node.children[tagName] && node.children[tagName].length > 1) { | ||
result[tagName] = []; | ||
for (let tag in node.child[tagName]) { | ||
if (Object.prototype.hasOwnProperty.call(node.child[tagName], tag)) { | ||
for (let tag in node.children[tagName]) { | ||
if (Object.prototype.hasOwnProperty.call(node.children[tagName], tag)) { | ||
result[tagName].push( | ||
traversableToJSON(node.child[tagName][tag], options, tagName), | ||
traversableToJSON(node.children[tagName][tag], options, tagName), | ||
); | ||
@@ -543,3 +556,3 @@ } | ||
const subResult = traversableToJSON( | ||
node.child[tagName][0], | ||
node.children[tagName][0], | ||
options, | ||
@@ -546,0 +559,0 @@ tagName, |
{ | ||
"name": "arraybuffer-xml-parser", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Parse XML files contained in an array buffer", | ||
@@ -37,5 +37,4 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"@babel/plugin-transform-modules-commonjs": "^7.15.0", | ||
"@babel/plugin-transform-modules-commonjs": "^7.15.4", | ||
"@types/jest": "^27.0.1", | ||
"base64-arraybuffer": "^1.0.1", | ||
"cheminfo-build": "^1.1.11", | ||
@@ -48,3 +47,4 @@ "eslint": "^7.32.0", | ||
"prettier": "^2.3.2", | ||
"rollup": "^2.56.3" | ||
"rollup": "^2.56.3", | ||
"uint8-base64": "^0.1.1" | ||
}, | ||
@@ -51,0 +51,0 @@ "dependencies": { |
@@ -48,17 +48,18 @@ # arraybuffer-xml-parser | ||
| Option | Description | | ||
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | ||
| attributeNamePrefix | prepend given string to attribute name for identification | | ||
| attributesNodeName | (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 | | ||
| dynamicTypingNodeValue | Parse the value of text node to float, integer, or boolean. | | ||
| dynamicTypingAttributeValue | Parse the value of an attribute to float, integer, or boolean. | | ||
| trimValues | trim string values of an attribute or node | | ||
| cdataTagName | If specified, parser parse CDATA as nested tag instead of adding it's value to parent tag. | | ||
| 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. | | ||
| attributeValueProcessor | 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. They are kept as Uint8Array. | | ||
| Option | Description | Default value | | ||
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | | ||
| trimValues | trim string values of an attribute or node | `true` | | ||
| attributeNamePrefix | prepend given string to attribute name for identification | `'@\_'` | | ||
| attributesNodeName | (Valid name) Group all the attributes as properties of given name. | `false` | | ||
| ignoreAttributes | Ignore attributes to be parsed. | `false` | | ||
| ignoreNameSpace | Remove namespace string from tag and attribute names. | `false` | | ||
| allowBooleanAttributes | a tag can have attributes without any value | `false` | | ||
| textNodeName | Name of the property containing text nodes | `'#text'` | | ||
| dynamicTypingAttributeValue | Parse the value of an attribute to float, integer, or boolean. | `true` | | ||
| dynamicTypingNodeValue | Parse the value of text node to float, integer, or boolean. | `true` | | ||
| cdataTagName | If specified, parser parse CDATA as nested tag instead of adding it's value to parent tag. | `false` | | ||
| 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. | `false` | | ||
| tagValueProcessor | Process tag value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. | `(value) => decoder.decode(value).replace(/\r/g, '')` | | ||
| attributeValueProcessor | Process attribute value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. | `(value) => value` | | ||
| stopNodes | an array of tag names which are not required to be parsed. They are kept as Uint8Array. | `[]` | | ||
@@ -65,0 +66,0 @@ ## [API Documentation](https://cheminfo.github.io/arraybuffer-xml-parser/) |
@@ -10,13 +10,12 @@ const utf8Decoder = new TextDecoder(); | ||
export const defaultOptions = { | ||
trimValues: true, | ||
attributeNamePrefix: '@_', | ||
attributesNodeName: false, | ||
textNodeName: '#text', | ||
trimValues: true, | ||
ignoreAttributes: false, | ||
ignoreNameSpace: false, | ||
allowBooleanAttributes: false, | ||
dynamicTypingAttributeValue: true, | ||
allowBooleanAttributes: false, | ||
textNodeName: '#text', | ||
dynamicTypingNodeValue: true, | ||
@@ -23,0 +22,0 @@ arrayMode: false, |
@@ -44,6 +44,6 @@ import { XMLNode } from '../XMLNode'; | ||
: xmlData.subarray(dataIndex, dataIndex + dataSize); | ||
if (currentNode.val === undefined) { | ||
currentNode.val = value; | ||
if (currentNode.value === undefined) { | ||
currentNode.value = value; | ||
} else { | ||
currentNode.val = concat(currentNode.val, value); | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
@@ -55,7 +55,7 @@ } | ||
) { | ||
currentNode.child = []; | ||
if (currentNode.attrsMap === undefined) { | ||
currentNode.attrsMap = {}; | ||
currentNode.children = []; | ||
if (currentNode.attributes === undefined) { | ||
currentNode.attributes = {}; | ||
} | ||
currentNode.val = xmlData.subarray(currentNode.startIndex + 1, i); | ||
currentNode.value = xmlData.subarray(currentNode.startIndex + 1, i); | ||
} | ||
@@ -83,4 +83,4 @@ currentNode = currentNode.parent; | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.val = concat( | ||
currentNode.val, | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
@@ -128,3 +128,3 @@ ? arrayTrim(xmlData.subarray(dataIndex, dataSize + dataIndex)) | ||
currentNode.val = concat(currentNode.val, value); | ||
currentNode.value = concat(currentNode.value, value); | ||
} | ||
@@ -142,6 +142,6 @@ | ||
if (tagExp) { | ||
childNode.val = tagExp; | ||
childNode.value = tagExp; | ||
} | ||
} else { | ||
currentNode.val = concat(currentNode.val, tagExp); | ||
currentNode.value = concat(currentNode.value, tagExp); | ||
} | ||
@@ -177,4 +177,4 @@ | ||
if (currentNode.tagName !== '!xml') { | ||
currentNode.val = concat( | ||
currentNode.val, | ||
currentNode.value = concat( | ||
currentNode.value, | ||
options.trimValues | ||
@@ -200,3 +200,6 @@ ? arrayTrim(xmlData.subarray(dataIndex, dataIndex + dataSize)) | ||
if (tagAttributes) { | ||
childNode.attrsMap = parseAttributesString(tagAttributes, options); | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
@@ -215,3 +218,6 @@ currentNode.addChild(childNode); | ||
if (tagAttributes && shouldBuildAttributesMap) { | ||
childNode.attrsMap = parseAttributesString(tagAttributes, options); | ||
childNode.attributes = parseAttributesString( | ||
tagAttributes, | ||
options, | ||
); | ||
} | ||
@@ -218,0 +224,0 @@ currentNode.addChild(childNode); |
@@ -45,7 +45,7 @@ import { parseString } from 'dynamic-typing'; | ||
function stringParseValue(val, shouldParse) { | ||
if (shouldParse && typeof val === 'string') { | ||
return parseString(val); | ||
function stringParseValue(value, shouldParse) { | ||
if (shouldParse && typeof value === 'string') { | ||
return parseString(value); | ||
} else { | ||
return val === undefined ? '' : val; | ||
return value === undefined ? '' : value; | ||
} | ||
@@ -52,0 +52,0 @@ } |
@@ -5,2 +5,9 @@ import { parseString } from 'dynamic-typing'; | ||
/** | ||
* | ||
* @param {*} node | ||
* @param {*} options | ||
* @param {*} parentTagName | ||
* @returns | ||
*/ | ||
export function traversableToJSON(node, options, parentTagName) { | ||
@@ -11,17 +18,17 @@ const { dynamicTypingNodeValue, tagValueProcessor, arrayMode } = options; | ||
if (tagValueProcessor) { | ||
node.val = node.val && tagValueProcessor(node.val, node); | ||
node.value = node.value && tagValueProcessor(node.value, node); | ||
} | ||
if (typeof node.val === 'string' && dynamicTypingNodeValue) { | ||
node.val = parseString(node.val); | ||
if (typeof node.value === 'string' && dynamicTypingNodeValue) { | ||
node.value = parseString(node.value); | ||
} | ||
// when no child node or attr is present | ||
if ( | ||
(!node.child || isEmptyObject(node.child)) && | ||
(!node.attrsMap || isEmptyObject(node.attrsMap)) | ||
(!node.children || isEmptyObject(node.children)) && | ||
(!node.attributes || isEmptyObject(node.attributes)) | ||
) { | ||
return node.val === undefined ? '' : node.val; | ||
return node.value === undefined ? '' : node.value; | ||
} | ||
// otherwise create a textnode if node has some text | ||
if (node.val !== undefined && node.val.length !== 0) { | ||
if (node.value !== undefined && node.value.length !== 0) { | ||
const asArray = isTagNameInArrayMode( | ||
@@ -33,16 +40,16 @@ node.tagName, | ||
result[options.textNodeName] = asArray ? [node.val] : node.val; | ||
result[options.textNodeName] = asArray ? [node.value] : node.value; | ||
} | ||
merge(result, node.attrsMap, arrayMode); | ||
merge(result, node.attributes, arrayMode); | ||
const keys = Object.keys(node.child); | ||
const keys = Object.keys(node.children); | ||
for (let index = 0; index < keys.length; index++) { | ||
const tagName = keys[index]; | ||
if (node.child[tagName] && node.child[tagName].length > 1) { | ||
if (node.children[tagName] && node.children[tagName].length > 1) { | ||
result[tagName] = []; | ||
for (let tag in node.child[tagName]) { | ||
if (Object.prototype.hasOwnProperty.call(node.child[tagName], tag)) { | ||
for (let tag in node.children[tagName]) { | ||
if (Object.prototype.hasOwnProperty.call(node.children[tagName], tag)) { | ||
result[tagName].push( | ||
traversableToJSON(node.child[tagName][tag], options, tagName), | ||
traversableToJSON(node.children[tagName][tag], options, tagName), | ||
); | ||
@@ -53,3 +60,3 @@ } | ||
const subResult = traversableToJSON( | ||
node.child[tagName][0], | ||
node.children[tagName][0], | ||
options, | ||
@@ -56,0 +63,0 @@ tagName, |
export class XMLNode { | ||
constructor(tagName, parent, val) { | ||
constructor(tagName, parent, value) { | ||
this.tagName = tagName; | ||
this.parent = parent; | ||
this.child = {}; //child tags | ||
this.attrsMap = {}; //attributes map | ||
this.val = val; //text only | ||
this.children = Object.create({}); //child tags | ||
this.attributes = Object.create({}); //attributes map | ||
this.value = value; //text only | ||
this.startIndex = -1; | ||
} | ||
addChild(child) { | ||
if (Array.isArray(this.child[child.tagName])) { | ||
if (Array.isArray(this.children[child.tagName])) { | ||
//already presents | ||
this.child[child.tagName].push(child); | ||
this.children[child.tagName].push(child); | ||
} else { | ||
this.child[child.tagName] = [child]; | ||
this.children[child.tagName] = [child]; | ||
} | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51380
1169
79