Socket
Socket
Sign inDemoInstall

xml-js

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xml-js - npm Package Compare versions

Comparing version 1.2.2 to 1.3.0

6

bin/cli.js

@@ -29,3 +29,4 @@ #!/usr/bin/env node

{arg: 'full-tag', type: 'flag', option:'fullTagEmptyElement', desc: 'XML elements will always be in <a></a> form.'},
{arg: 'no-decl', type: 'flag', option:'ignoreDeclaration', desc: 'Declaration instruction <?xml ..?> will be ignored.'},
{arg: 'no-decl', type: 'flag', option:'ignoreDeclaration', desc: 'Declaration instruction <?xml?> will be ignored.'},
{arg: 'no-decl', type: 'flag', option:'ignoreInstruction', desc: 'Processing instruction <?...?> will be ignored.'},
{arg: 'no-attr', type: 'flag', option:'ignoreAttributes', desc: 'Attributes of elements will be ignored.'},

@@ -41,3 +42,4 @@ {arg: 'no-text', type: 'flag', option:'ignoreText', desc: 'Texts of elements will be ignored.'},

{arg: 'attributes-key', type: 'string', option:'attributesKey', desc: 'To change the default \'attributes\' key.'},
{arg: 'declaration-key', type: 'string', option:'declarationKey', desc: 'To change the default \'declaration\' key.'},
{arg: 'declaration-key', type: 'string', option:'declarationKey', desc: 'To change the default \'declaration\' key <?xml?>.'},
{arg: 'instruction-key', type: 'string', option:'instructionKey', desc: 'To change the default \'processing instruction\' key <?...?>.'},
{arg: 'type-key', type: 'string', option:'typeKey', desc: 'To change the default \'type\' key (applicable if --compact is not set).'},

@@ -44,0 +46,0 @@ {arg: 'name-key', type: 'string', option:'nameKey', desc: 'To change the default \'name\' key (applicable if --compact is not set).'},

var common = require('./common');
function validateOptions (userOptions) {
function validateOptions(userOptions) {
var options = common.copyOptions(userOptions);
common.ensureFlagExists('ignoreDeclaration', options);
common.ensureFlagExists('ignoreInstruction', options);
common.ensureFlagExists('ignoreAttributes', options);

@@ -14,2 +15,3 @@ common.ensureFlagExists('ignoreText', options);

common.ensureFlagExists('indentCdata', options);
common.ensureFlagExists('indentInstruction', options);
common.ensureFlagExists('fullTagEmptyElement', options);

@@ -21,2 +23,3 @@ common.ensureSpacesExists(options);

common.ensureKeyExists('declaration', options);
common.ensureKeyExists('instruction', options);
common.ensureKeyExists('attributes', options);

@@ -33,7 +36,7 @@ common.ensureKeyExists('text', options);

function writeIndentation (options, depth, firstLine) {
function writeIndentation(options, depth, firstLine) {
return (!firstLine && options.spaces ? '\n' : '') + Array(depth + 1).join(options.spaces);
}
function writeAttributes (attributes) {
function writeAttributes(attributes) {
var key, result = '';

@@ -48,23 +51,33 @@ for (key in attributes) {

function writeDeclaration (declaration, options) {
function writeDeclaration(declaration, options) {
return '<?xml' + writeAttributes(declaration[options.attributesKey]) + '?>';
}
function writeComment (comment, options) {
function writeInstruction(instruction, options) {
var key;
for (key in instruction) {
if (instruction.hasOwnProperty(key)) {
break;
}
}
return '<?' + key + (instruction[key] ? ' ' + instruction[key] : '') + '?>';
}
function writeComment(comment, options) {
return options.ignoreComment ? '' : '<!--' + comment + '-->';
}
function writeCdata (cdata, options) {
function writeCdata(cdata, options) {
return options.ignoreCdata ? '' : '<![CDATA[' + cdata + ']]>';
}
function writeDoctype (doctype, options) {
function writeDoctype(doctype, options) {
return options.ignoreDoctype ? '' : '<!DOCTYPE ' + doctype + '>';
}
function writeText (text, options) {
function writeText(text, options) {
return options.ignoreText ? '' : text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}
function hasContent (element, options) {
function hasContent(element, options) {
var i;

@@ -84,2 +97,7 @@ if (element.elements && element.elements.length) {

break; // skip to next key
case 'instruction':
if (options.indentInstruction) {
return true;
}
break; // skip to next key
case 'doctype':

@@ -97,3 +115,3 @@ case 'comment':

function writeElement (element, options, depth) {
function writeElement(element, options, depth) {
var xml = '';

@@ -117,3 +135,3 @@ xml += '<' + element.name;

function writeElements (elements, options, depth, firstLine) {
function writeElements(elements, options, depth, firstLine) {
return elements.reduce(function (xml, element) {

@@ -127,2 +145,6 @@ var indent = writeIndentation(options, depth, firstLine && !xml);

case 'text': return xml + (options.indentText ? indent : '') + writeText(element[options.textKey], options);
case 'instruction':
var instruction = {};
instruction[element[options.nameKey]] = element[options.instructionKey];
return xml + (options.indentInstruction ? indent : '') + writeInstruction(instruction, options);
}

@@ -132,3 +154,3 @@ }, '');

function hasContentCompact (element, options, anyContent) {
function hasContentCompact(element, options, anyContent) {
var key;

@@ -151,5 +173,10 @@ for (key in element) {

break; // skip to next key
case options.instructionKey:
if (options.indentInstruction || anyContent) {
return true;
}
break; // skip to next key
case options.doctypeKey:
case options.commentKey:
case options.declarationKey:
case options.instructionKey:
return true;

@@ -164,3 +191,3 @@ default:

function writeElementCompact (element, name, options, depth, indent) {
function writeElementCompact(element, name, options, depth, indent) {
var xml = '';

@@ -186,3 +213,3 @@ if (name) {

function writeElementsCompact (element, options, depth, firstLine) {
function writeElementsCompact(element, options, depth, firstLine) {
var i, key, nodes, xml = '';

@@ -195,2 +222,3 @@ for (key in element) {

case options.declarationKey: xml += writeDeclaration(nodes[i], options); break;
case options.instructionKey: xml += (options.indentInstruction ? writeIndentation(options, depth, firstLine) : '') + writeInstruction(nodes[i], options); break;
case options.attributesKey: case options.parentKey: break; // skip

@@ -197,0 +225,0 @@ case options.textKey: xml += (options.indentText ? writeIndentation(options, depth, firstLine) : '') + writeText(nodes[i], options); break;

var sax = require('sax');
var expat /*= require('node-expat');*/ = {on: function () {}, parse: function () {}};
var expat /*= require('node-expat');*/ = { on: function () { }, parse: function () { } };
var common = require('./common');
var options;
var pureJsParser = 1; //true;
var pureJsParser = true;
var currentElement;
function validateOptions (userOptions) {
function validateOptions(userOptions) {
options = common.copyOptions(userOptions);
common.ensureFlagExists('ignoreDeclaration', options);
common.ensureFlagExists('ignoreInstruction', options);
common.ensureFlagExists('ignoreAttributes', options);

@@ -25,2 +26,3 @@ common.ensureFlagExists('ignoreText', options);

common.ensureKeyExists('declaration', options);
common.ensureKeyExists('instruction', options);
common.ensureKeyExists('attributes', options);

@@ -38,3 +40,3 @@ common.ensureKeyExists('text', options);

function nativeType (value) {
function nativeType(value) {
var nValue = Number(value);

@@ -53,3 +55,3 @@ if (!isNaN(nValue)) {

function addField (type, value, options) {
function addField(type, value, options) {
if (options.compact) {

@@ -71,5 +73,15 @@ if (!currentElement[options[type + 'Key']] && options.alwaysArray) {

}
var element = {};
var key, element = {};
element[options.typeKey] = type;
element[options[type + 'Key']] = value;
if (typeof value === 'object') {
for (key in value) {
if (value.hasOwnProperty(key)) {
element[options.nameKey] = key;
element[options[type + 'Key']] = value[key];
break;
}
}
} else {
element[options[type + 'Key']] = value;
}
if (options.addParent) {

@@ -82,27 +94,39 @@ element[options.parentKey] = currentElement;

function onDeclaration (declaration) {
if (options.ignoreDeclaration) {
return;
}
if (currentElement[options.declarationKey]) {
return;
}
currentElement[options.declarationKey] = {};
while (declaration.body) {
var attribute = declaration.body.match(/([\w:-]+)\s*=\s*"([^"]*)"|'([^']*)'|(\w+)\s*/);
if (!attribute) {
break;
function onInstruction(instruction) {
if (instruction.name.toLowerCase() === 'xml') {
if (options.ignoreDeclaration) {
return;
}
if (!currentElement[options.declarationKey][options.attributesKey]) {
currentElement[options.declarationKey][options.attributesKey] = {};
currentElement[options.declarationKey] = {};
while (instruction.body) {
var attribute = instruction.body.match(/([\w:-]+)\s*=\s*"([^"]*)"|'([^']*)'|(\w+)\s*/);
if (!attribute) {
break;
}
if (!currentElement[options.declarationKey][options.attributesKey]) {
currentElement[options.declarationKey][options.attributesKey] = {};
}
currentElement[options.declarationKey][options.attributesKey][attribute[1]] = attribute[2];
instruction.body = instruction.body.slice(attribute[0].length); // advance the string
}
currentElement[options.declarationKey][options.attributesKey][attribute[1]] = attribute[2];
declaration.body = declaration.body.slice(attribute[0].length); // advance the string
if (options.addParent) {
currentElement[options.declarationKey][options.parentKey] = currentElement;
}
} else {
if (options.ignoreInstruction) {
return;
}
if (options.trim) {
instruction.body = instruction.body.trim();
}
if (options.sanitize) {
instruction.body = common.sanitize(instruction.body);
}
var value = {};
value[instruction.name] = instruction.body;
addField('instruction', value, options);
}
if (options.addParent) {
currentElement[options.declarationKey][options.parentKey] = currentElement;
}
}
function onStartElement (name, attributes) {
function onStartElement(name, attributes) {
var key, element;

@@ -130,3 +154,2 @@ if (typeof name === 'object') {

}
element[options.parentKey] = currentElement;
if (!(name in currentElement) && options.alwaysArray) {

@@ -153,3 +176,2 @@ currentElement[name] = [];

}
element[options.parentKey] = currentElement;
if (options.alwaysChildren) {

@@ -160,6 +182,9 @@ element[options.elementsKey] = [];

}
// if (options.addParent) {
element[options.parentKey] = currentElement;
// }
currentElement = element;
}
function onText (text) {
function onText(text) {
if (options.ignoreText) {

@@ -183,3 +208,3 @@ return;

function onComment (comment) {
function onComment(comment) {
if (options.ignoreComment) {

@@ -197,3 +222,3 @@ return;

function onEndElement (name) {
function onEndElement(name) {
var parentElement = currentElement[options.parentKey];

@@ -206,3 +231,3 @@ if (!options.addParent) {

function onCdata (cdata) {
function onCdata(cdata) {
if (options.ignoreCdata) {

@@ -217,3 +242,3 @@ return;

function onDoctype (doctype) {
function onDoctype(doctype) {
if (options.ignoreDoctype) {

@@ -229,3 +254,3 @@ return;

function onError (error) {
function onError(error) {
error.note = error; //console.error(error);

@@ -250,3 +275,3 @@ }

parser.ondoctype = onDoctype;
parser.onprocessinginstruction = onDeclaration;
parser.onprocessinginstruction = onInstruction;
} else {

@@ -253,0 +278,0 @@ parser.on('startElement', onStartElement);

@@ -16,2 +16,3 @@ var common = require('./common');

parentKey = 'compact' in options && options.compact ? '_parent' : 'parent';
// parentKey = ptions.compact ? '_parent' : 'parent'; // consider this
if ('addParent' in options && options.addParent) {

@@ -23,2 +24,2 @@ json = JSON.stringify(js, function (k, v) { return k === parentKey? '_' : v; }, options.spaces);

return json.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
};
};
{
"name": "xml-js",
"version": "1.2.2",
"version": "1.3.0",
"description": "A convertor between XML text and Javascript object / JSON text.",

@@ -44,21 +44,3 @@ "repository": {

"bin": "./bin/cli.js",
"dependencies": {
"sax": "^1.2.1"
},
"devDependencies": {
"biased-opener": "^0.2.8",
"browser-sync": "^2.18.6",
"cash-cat": "^0.2.0",
"codacy-coverage": "^2.0.2",
"codeclimate-test-reporter": "^0.4.0",
"coveralls": "^2.13.0",
"cross-env": "^4.0.0",
"globify": "^2.0.0",
"istanbul": "^0.4.5",
"jasmine": "^2.6.0",
"nodemon": "^1.11.0",
"npm-run-all": "^4.0.1",
"typescript": "^2.2.2",
"watch": "^1.0.1"
},
"types": "./types/index.d.ts",
"scripts": {

@@ -90,3 +72,21 @@ "debug": "nodemon --inspect --watch lib/ --watch test/ --debug-brk test/index.js",

},
"types": "./types/index.d.ts"
"dependencies": {
"sax": "^1.2.1"
},
"devDependencies": {
"biased-opener": "^0.2.8",
"browser-sync": "^2.18.6",
"cash-cat": "^0.2.0",
"codacy-coverage": "^2.0.2",
"codeclimate-test-reporter": "^0.4.0",
"coveralls": "^2.13.0",
"cross-env": "^4.0.0",
"globify": "^2.0.0",
"istanbul": "^0.4.5",
"jasmine": "^2.6.0",
"nodemon": "^1.11.0",
"npm-run-all": "^4.0.1",
"typescript": "^2.2.2",
"watch": "^1.0.1"
}
}

@@ -33,3 +33,3 @@ ![XML ⇔ JS/JSON](http://nashwaan.github.io/xml-js/images/logo.svg)

* **Fully XML Compliant**:
Can parse: elements, attributes, texts, comments, CData, DOCTYPE, and XML declarations.
Can parse: elements, attributes, texts, comments, CData, DOCTYPE, XML declarations, and Processing Instructions.

@@ -62,3 +62,3 @@ * **Reversible**:

Most XML to JSON convertors (including online convertors) convert `<a/>` to some compact output like `{"a":{}}`
Most XML to JSON converters (including online converters) convert `<a/>` to some compact output like `{"a":{}}`
instead of non-compact output like `{"elements":[{"type":"element","name":"a"}]}`.

@@ -69,6 +69,6 @@

which has merged both `<a>` elements into an array! If you try to convert this back to xml, you will get `<a x="1"/><a x="3"/><b x="2"/>`
which has not preserved the order of elements! This is an inherit limitation in the compact representation
which has not preserved the order of elements! This is an inherent limitation in the compact representation
because output like `{a:{_:{x:"1"}}, b:{_:{x:"2"}}, a:{_:{x:"3"}}}` is illegal (same property name `a` should not appear twice in an object).
The non-compact output, which is supported by this library, will produce more information and always gurantees the order of the elements as they appeared in the XML file.
The non-compact output, which is supported by this library, will produce more information and always guarantees the order of the elements as they appeared in the XML file.

@@ -79,4 +79,7 @@ Another drawback of compact output is the resultant element can be an object or an array and therefore makes the client code a little awkwards in terms of the extra check needed on object type before processing.

This library provides both options. Use `{compact: false}` if you are not sure because it preserves everything;
otherwise use `{compact: true}` if you want to save space and you don't care about mixing elements of same type and loosing their order.
otherwise use `{compact: true}` if you want to save space and you don't care about mixing elements of same type and losing their order.
# Usage

@@ -126,2 +129,3 @@

| `<?xml?>` | `{"_declaration":{}}` | `{"declaration":{}}` |
| `<?go there?>` | `{"_instruction":{"go":"there"}}` | `{"elements":[{"type":"instruction","name":"go","instruction":"there"}]}` |
| `<?xml version="1.0" encoding="utf-8"?>` | `{"_declaration":{"_attributes":{"version":"1.0","encoding":"utf-8"}}}` | `{"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}}}` |

@@ -165,2 +169,3 @@ | `<!--Hello, World!-->` | `{"_comment":"Hello, World!"}` | `{"elements":[{"type":"comment","comment":"Hello, World!"}]}` |

| `ignoreDeclaration` | `false` | Whether to ignore writing declaration directives of xml. For example, `<?xml?>` will be ignored. |
| `ignoreInstruction` | `false` | Whether to ignore writing processing instruction of xml. For example, `<?go there?>` will be ignored. |
| `ignoreAttributes` | `false` | Whether to ignore writing attributes of the elements. For example, `x="1"` in `<a x="1"></a>` will be ignored |

@@ -191,3 +196,3 @@ | `ignoreComment` | `false` | Whether to ignore writing comments of the elements. That is, no `<!-- -->` will be generated. |

| `compact` | `false` | Whether to produce detailed object or compact object. |
| `trim` | `false` | Whether to trim white space characters that may exist before and after the text. |
| `trim` | `false` | Whether to trim whitespace characters that may exist before and after the text. |
| `sanitize` | `false` | Whether to replace `&` `<` `>` `"` `'` with `&amp;` `&lt;` `&gt;` `&quot;` `&#39;` respectively in the resultant text. |

@@ -199,2 +204,3 @@ | `nativeType` | `false` | Whether to attempt converting text of numerals or of boolean values to native type. For example, `"123"` will be `123` and `"true"` will be `true` |

| `ignoreDeclaration` | `false` | Whether to ignore writing declaration property. That is, no `declaration` property will be generated. |
| `ignoreInstruction` | `false` | Whether to ignore writing processing instruction property. That is, no `instruction` property will be generated. |
| `ignoreAttributes` | `false` | Whether to ignore writing attributes of elements.That is, no `attributes` property will be generated. |

@@ -210,3 +216,3 @@ | `ignoreComment` | `false` | Whether to ignore writing comments of the elements. That is, no `comment` will be generated. |

|:--------------------|:--------|:------------|
| `spaces` | `0` | Number of spaces to be used for indenting JSON output. Passing characters like `' '` or `'\t'` are also accpeted. |
| `spaces` | `0` | Number of spaces to be used for indenting JSON output. Passing characters like `' '` or `'\t'` are also accepted. |

@@ -220,2 +226,3 @@ ## Options for Changing Key Names

| `declarationKey` | `"declaration"` or `"_declaration"` | Name of the property key which will be used for the declaration. For example, if `declarationKey: '$declaration'` then output of `<?xml?>` will be `{"$declaration":{}}` *(in compact form)* |
| `instructionKey` | `"instruction"` or `"_instruction"` | Name of the property key which will be used for the processing instruction. For example, if `instructionKey: '$instruction'` then output of `<?go there?>` will be `{"$instruction":{"go":"there"}}` *(in compact form)* |
| `attributesKey` | `"attributes"` or `"_attributes"` | Name of the property key which will be used for the attributes. For example, if `attributesKey: '$attributes'` then output of `<a x="hello"/>` will be `{"a":{$attributes:{"x":"hello"}}}` *(in compact form)* |

@@ -287,3 +294,4 @@ | `textKey` | `"text"` or `"_text"` | Name of the property key which will be used for the text. For example, if `textKey: '$text'` then output of `<a>hi</a>` will be `{"a":{"$text":"Hi"}}` *(in compact form)* |

--full-tag XML elements will always be in <a></a> form.
--no-decl Declaration instruction <?xml ..?> will be ignored.
--no-decl Declaration directive <?xml?> will be ignored.
--no-inst Processing instruction <?...?> will be ignored.
--no-attr Attributes of elements will be ignored.

@@ -306,2 +314,3 @@ --no-text Texts of elements will be ignored.

--declaration-key To change the default 'declaration' key.
--instruction-key To change the default 'processing instruction' key.
--type-key To change the default 'type' key (applicable if --compact is not set).

@@ -308,0 +317,0 @@ --name-key To change the default 'name' key (applicable if --compact is not set).

export interface ElementCompact {
[key: string]: any
_declaration?: {
_attributes?: {
version?: string | number
encoding?: string | number
}
}
_instruction?: {
[key: string]: string
}
_attributes?: {

@@ -9,8 +18,2 @@ [key: string]: string | number

_comment?: string
_declaration?: {
_attributes?: {
version?: string | number
encoding?: string | number
}
}
_text?: string | number

@@ -20,2 +23,9 @@ }

export interface Element {
declaration?: {
attributes?: {
version: string | number
encoding: string | number
}
}
instruction?: string
attributes?: {

@@ -27,8 +37,2 @@ [key: string]: string | number

comment?: string
declaration?: {
attributes?: {
version: string | number
encoding: string | number
}
}
text?: string | number | boolean

@@ -57,2 +61,3 @@ type?: string

indentCdata?: boolean
indentInstruction?: boolean
fullTagEmptyElement?: boolean

@@ -63,2 +68,3 @@ }

ignoreDeclaration?: boolean
ignoreInstruction?: boolean
ignoreAttributes?: boolean

@@ -73,2 +79,3 @@ ignoreComment?: boolean

declarationKey?: string
instructionKey?: string
attributesKey?: string

@@ -75,0 +82,0 @@ textKey?: string

@@ -10,2 +10,6 @@ import { Element, ElementCompact } from './index'

// Processing Instruction
const instructionCompact: ElementCompact = { _instruction: { go: 'there' }};
const instruction: Element = { elements:[{ type: 'instruction', name: 'go', instruction: 'there' }]};
// Comment

@@ -12,0 +16,0 @@ const commentCompact: ElementCompact = { _comment : 'Hello, World!' };

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc