Socket
Socket
Sign inDemoInstall

xmlbuilder2

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xmlbuilder2 - npm Package Compare versions

Comparing version 0.0.4 to 0.0.7

22

lib/builder/CastAsNode.d.ts

@@ -1,2 +0,2 @@

import { dom } from "@oozcitak/dom";
import { Node, Document, DocumentType, DocumentFragment, Attr, Text, CDATASection, Comment, ProcessingInstruction, Element } from "@oozcitak/dom/lib/dom/interfaces";
import { XMLBuilderNode, CastAsNode } from "./interfaces";

@@ -17,21 +17,21 @@ /**

/** @inheritdoc */
get node(): dom.Interfaces.Node;
get node(): Node;
/** @inheritdoc */
get document(): dom.Interfaces.Document;
get document(): Document;
/** @inheritdoc */
get documentType(): dom.Interfaces.DocumentType;
get documentType(): DocumentType;
/** @inheritdoc */
get documentFragment(): dom.Interfaces.DocumentFragment;
get documentFragment(): DocumentFragment;
/** @inheritdoc */
get attr(): dom.Interfaces.Attr;
get attr(): Attr;
/** @inheritdoc */
get text(): dom.Interfaces.Text;
get text(): Text;
/** @inheritdoc */
get cdataSection(): dom.Interfaces.CDATASection;
get cdataSection(): CDATASection;
/** @inheritdoc */
get comment(): dom.Interfaces.Comment;
get comment(): Comment;
/** @inheritdoc */
get processingInstruction(): dom.Interfaces.ProcessingInstruction;
get processingInstruction(): ProcessingInstruction;
/** @inheritdoc */
get element(): dom.Interfaces.Element;
get element(): Element;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/dom/lib/util");
/**

@@ -14,3 +14,3 @@ * Returns underlying DOM nodes.

constructor(builder) {
this._node = dom_1.util.Cast.asNode(builder);
this._node = util_1.Cast.asNode(builder);
}

@@ -27,3 +27,3 @@ /** @inheritdoc */

get document() {
if (dom_1.util.Guard.isDocumentNode(this._node)) {
if (util_1.Guard.isDocumentNode(this._node)) {
return this._node;

@@ -37,3 +37,3 @@ }

get documentType() {
if (dom_1.util.Guard.isDocumentTypeNode(this._node)) {
if (util_1.Guard.isDocumentTypeNode(this._node)) {
return this._node;

@@ -47,3 +47,3 @@ }

get documentFragment() {
if (dom_1.util.Guard.isDocumentFragmentNode(this._node)) {
if (util_1.Guard.isDocumentFragmentNode(this._node)) {
return this._node;

@@ -57,3 +57,3 @@ }

get attr() {
if (dom_1.util.Guard.isAttrNode(this._node)) {
if (util_1.Guard.isAttrNode(this._node)) {
return this._node;

@@ -67,3 +67,3 @@ }

get text() {
if (dom_1.util.Guard.isTextNode(this._node)) {
if (util_1.Guard.isTextNode(this._node)) {
return this._node;

@@ -77,3 +77,3 @@ }

get cdataSection() {
if (dom_1.util.Guard.isCDATASectionNode(this._node)) {
if (util_1.Guard.isCDATASectionNode(this._node)) {
return this._node;

@@ -87,3 +87,3 @@ }

get comment() {
if (dom_1.util.Guard.isCommentNode(this._node)) {
if (util_1.Guard.isCommentNode(this._node)) {
return this._node;

@@ -97,3 +97,3 @@ }

get processingInstruction() {
if (dom_1.util.Guard.isProcessingInstructionNode(this._node)) {
if (util_1.Guard.isProcessingInstructionNode(this._node)) {
return this._node;

@@ -107,3 +107,3 @@ }

get element() {
if (dom_1.util.Guard.isElementNode(this._node)) {
if (util_1.Guard.isElementNode(this._node)) {
return this._node;

@@ -110,0 +110,0 @@ }

@@ -1,3 +0,2 @@

import { XMLBuilderImpl } from './XMLBuilderImpl';
import { XMLBuilderNodeImpl } from './XMLBuilderNodeImpl';
export { XMLBuilderImpl, XMLBuilderNodeImpl };
import { XMLBuilderImpl } from "./XMLBuilderImpl";
export { XMLBuilderImpl };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/util");

@@ -8,16 +7,16 @@ const XMLBuilderImpl_1 = require("./XMLBuilderImpl");

const XMLBuilderNodeImpl_1 = require("./XMLBuilderNodeImpl");
exports.XMLBuilderNodeImpl = XMLBuilderNodeImpl_1.XMLBuilderNodeImpl;
const dom_1 = require("@oozcitak/dom/lib/dom");
// Apply XMLBuilder mixin
util_1.applyMixin(dom_1.dom.Node, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.Element, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.Attr, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.CharacterData, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.CDATASection, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.Comment, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.Text, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.ProcessingInstruction, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.DocumentType, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.DocumentFragment, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.Document, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.dom.XMLDocument, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Node, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Element, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Attr, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.CharacterData, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.CDATASection, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Comment, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Text, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.ProcessingInstruction, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.DocumentType, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.DocumentFragment, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.Document, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
util_1.applyMixin(dom_1.XMLDocument, XMLBuilderNodeImpl_1.XMLBuilderNodeImpl, "remove");
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

import { dom } from "@oozcitak/dom";
import { Node, Document, DocumentType, DocumentFragment, Attr, Text, CDATASection, Comment, ProcessingInstruction, Element } from "@oozcitak/dom/lib/dom/interfaces";
/**

@@ -284,9 +284,8 @@ * Defines the options used while creating an XML document.

*/
export interface WriterOptions {
declare type BaseWriterOptions = {
/**
* Output format. Defaults to `"text"`.
* - `"text"` - Serializes the document as a string in XML format.
* Output format. Defaults to `"xml"`.
* - `"xml"` - Serializes the document as a string in XML format.
* - `"map"` - Serializes the document as an object using `Map`s and
* `Array`s. Note that this is the preferred format since a `Map` preserves
* insertion order of nodes as opposed to `Object`.
* `Array`s.
* - `"object"` - Serializes the document as an object using `Object`s and

@@ -296,3 +295,24 @@ * `Array`s.

*/
format?: "text" | "map" | "object" | "json";
format?: "xml" | "map" | "object" | "json";
};
/**
* Defines the options passed to the map writer.
*/
export declare type MapWriterOptions = BaseWriterOptions & {
/** @inheritdoc */
format?: "map";
};
/**
* Defines the options passed to the object writer.
*/
export declare type ObjectWriterOptions = BaseWriterOptions & {
/** @inheritdoc */
format?: "object";
};
/**
* Defines the options passed to the object writer.
*/
export declare type StringWriterOptions = BaseWriterOptions & {
/** @inheritdoc */
format?: "xml";
/**

@@ -366,4 +386,33 @@ * Suppresses the XML declaration from the output. Defaults to `false`.

noDoubleEncoding?: boolean;
}
};
/**
* Defines the options passed to the JSON writer.
*/
export declare type JSONWriterOptions = BaseWriterOptions & {
/** @inheritdoc */
format?: "json";
/**
* Pretty-prints the XML tree. Defaults to `false`.
*/
prettyPrint?: boolean;
/**
* Determines the indentation string for pretty printing. Defaults to two
* space characters.
*/
indent?: string;
/**
* Determines the newline string for pretty printing. Defaults to `"\n"`.
*/
newline?: string;
/**
* Defines a fixed number of indentations to add to every line. Defaults to
* `0`.
*/
offset?: number;
};
/**
* Defines the options passed to the writer.
*/
export declare type WriterOptions = StringWriterOptions | ObjectWriterOptions | JSONWriterOptions | MapWriterOptions;
/**
* Defines a recursive type that can represent objects, arrays and maps of

@@ -402,2 +451,12 @@ * serialized nodes.

/**
* Represents the type of a variable that is a JS object defining
* processing instructions.
*/
export declare type PIObject = Map<string, string> | string[] | {
/**
* Processing instruction target/data pairs
*/
[key: string]: string;
};
/**
* Serves as an entry point to builder functions.

@@ -584,2 +643,12 @@ */

/**
* Creates new processing instruction nodes by expanding the given object and
* appends them to the list of child nodes.
*
* @param contents - a JS object containing processing instruction targets
* and values or an array of strings
*
* @returns current element node
*/
ins(target: PIObject): XMLBuilderNode;
/**
* Updates XML declaration.

@@ -652,10 +721,20 @@ *

* Traverses through the child nodes of an element node.
*
* @param callback - a callback function to apply to each node
* @param thisArg - value to use as this when executing callback
*/
traverseChildren(): IterableIterator<XMLBuilderNode>;
forEachChild(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/**
* Traverses through the attributes of an element node.
*
* @param callback - a callback function to apply to each attribute
* @param thisArg - value to use as this when executing callback
*/
traverseAttributes(): IterableIterator<XMLBuilderNode>;
forEachAttribute(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/**
* Traverses through descendant nodes of an element node in tree order.
*
* @param callback - a callback function to apply to each node
* @param thisArg - value to use as this when executing callback
*
* For example, for the following tree:

@@ -671,5 +750,9 @@ * ```

*/
traverseDescendants(): IterableIterator<XMLBuilderNode>;
forEachDescendant(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/**
* Traverses through ancestor nodes of an element node in reverse tree order.
*
* @param callback - a callback function to apply to each node
* @param thisArg - value to use as this when executing callback
*
* For example, for the following tree:

@@ -685,3 +768,3 @@ * ```

*/
traverseAncestors(): IterableIterator<XMLBuilderNode>;
forEachAncestor(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/**

@@ -692,3 +775,3 @@ * Converts the node into its string representation.

*/
toString(writerOptions?: WriterOptions): string;
toString(writerOptions?: JSONWriterOptions | StringWriterOptions): string;
/**

@@ -699,3 +782,3 @@ * Converts the node into its object representation.

*/
toObject(writerOptions?: WriterOptions): XMLSerializedValue;
toObject(writerOptions?: MapWriterOptions | ObjectWriterOptions): XMLSerializedValue;
/**

@@ -719,40 +802,40 @@ * Converts the entire XML document into its string or object representation.

*/
readonly node: dom.Interfaces.Node;
readonly node: Node;
/**
* Returns the underlying DOM document node.
*/
readonly document: dom.Interfaces.Document;
readonly document: Document;
/**
* Returns the underlying DOM document type node.
*/
readonly documentType: dom.Interfaces.DocumentType;
readonly documentType: DocumentType;
/**
* Returns the underlying DOM document fragment node.
*/
readonly documentFragment: dom.Interfaces.DocumentFragment;
readonly documentFragment: DocumentFragment;
/**
* Returns the underlying DOM attr node.
*/
readonly attr: dom.Interfaces.Attr;
readonly attr: Attr;
/**
* Returns the underlying DOM text node.
*/
readonly text: dom.Interfaces.Text;
readonly text: Text;
/**
* Returns the underlying DOM cdata section node.
*/
readonly cdataSection: dom.Interfaces.CDATASection;
readonly cdataSection: CDATASection;
/**
* Returns the underlying DOM comment node.
*/
readonly comment: dom.Interfaces.Comment;
readonly comment: Comment;
/**
* Returns the underlying DOM processing instruction node.
*/
readonly processingInstruction: dom.Interfaces.ProcessingInstruction;
readonly processingInstruction: ProcessingInstruction;
/**
* Returns the underlying DOM element node.
*/
readonly element: dom.Interfaces.Element;
readonly element: Element;
}
export {};

@@ -5,2 +5,3 @@ "use strict";

const dom_1 = require("@oozcitak/dom");
const dom_2 = require("@oozcitak/dom/lib/dom");
const util_1 = require("@oozcitak/util");

@@ -18,4 +19,4 @@ const validator_1 = require("../validator");

*/
constructor(options) {
options = options || {};
constructor(options = {}) {
dom_2.dom.setFeatures(false);
this._validate = new validator_1.ValidatorImpl(options.version || "1.0");

@@ -50,4 +51,4 @@ this._options = util_1.applyDefaults(options, interfaces_1.DefaultBuilderOptions);

contents = "<TEMP_ROOT>" + contents + "</TEMP_ROOT>";
const domParser = new dom_1.parser.DOMParser();
const doc = domParser.parseFromString(contents, dom_1.parser.MimeType.XML);
const domParser = new dom_1.DOMParser();
const doc = domParser.parseFromString(contents, "text/xml");
this._setOptions(doc);

@@ -91,4 +92,4 @@ /* istanbul ignore next */

// XML document
const domParser = new dom_1.parser.DOMParser();
builder = XMLBuilderNodeImpl_1.XMLBuilderNodeImpl._FromNode(domParser.parseFromString(contents, dom_1.parser.MimeType.XML));
const domParser = new dom_1.DOMParser();
builder = XMLBuilderNodeImpl_1.XMLBuilderNodeImpl._FromNode(domParser.parseFromString(contents, "text/xml"));
this._setOptions(builder);

@@ -109,3 +110,4 @@ }

_createEmptyDocument() {
const doc = dom_1.implementation.createDocument(null, 'root');
const impl = new dom_1.DOMImplementation();
const doc = impl.createDocument(null, 'root');
/* istanbul ignore else */

@@ -112,0 +114,0 @@ if (doc.documentElement) {

@@ -1,3 +0,3 @@

import { XMLBuilderOptions, XMLBuilderNode, AttributesObject, ExpandObject, WriterOptions, XMLSerializedValue, Validator, DTDOptions, CastAsNode } from "./interfaces";
import { dom } from "@oozcitak/dom";
import { XMLBuilderOptions, XMLBuilderNode, AttributesObject, ExpandObject, WriterOptions, XMLSerializedValue, Validator, DTDOptions, CastAsNode, PIObject } from "./interfaces";
import { Document, Node } from "@oozcitak/dom/lib/dom/interfaces";
/**

@@ -8,3 +8,2 @@ * Represents a mixin that extends XML nodes to implement easy to use and

export declare class XMLBuilderNodeImpl implements XMLBuilderNode {
private static _algo;
private _castAsNode;

@@ -32,3 +31,3 @@ private _builderOptions?;

/** @inheritdoc */
ins(target: string, content?: string): XMLBuilderNode;
ins(target: string | PIObject, content?: string): XMLBuilderNode;
/** @inheritdoc */

@@ -59,9 +58,9 @@ dec(options: {

/** @inheritdoc */
traverseChildren(): IterableIterator<XMLBuilderNode>;
forEachChild(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/** @inheritdoc */
traverseAttributes(): IterableIterator<XMLBuilderNode>;
forEachAttribute(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/** @inheritdoc */
traverseDescendants(): IterableIterator<XMLBuilderNode>;
forEachDescendant(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/** @inheritdoc */
traverseAncestors(): IterableIterator<XMLBuilderNode>;
forEachAncestor(callback: (node: XMLBuilderNode) => void, thisArg?: any): XMLBuilderNode;
/** @inheritdoc */

@@ -103,7 +102,7 @@ toString(writerOptions?: WriterOptions): string;

*/
protected get _doc(): dom.Interfaces.Document;
protected get _doc(): Document;
/**
* Converts a DOM node to an `XMLBuilder`.
*/
static _FromNode(node: dom.Interfaces.Node): XMLBuilderNode;
static _FromNode(node: Node): XMLBuilderNode;
/**

@@ -110,0 +109,0 @@ * Returns debug information for this node.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const interfaces_1 = require("./interfaces");
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/util");

@@ -9,2 +8,5 @@ const infra_1 = require("@oozcitak/infra");

const CastAsNode_1 = require("./CastAsNode");
const util_2 = require("@oozcitak/dom/lib/util");
const algorithm_1 = require("@oozcitak/dom/lib/algorithm");
const dom_1 = require("@oozcitak/dom");
/**

@@ -33,3 +35,28 @@ * Represents a mixin that extends XML nodes to implement easy to use and

let attributes;
if (util_1.isObject(p1)) {
let lastChild = null;
if (util_1.isString(p1) && /^\s*</.test(p1)) {
// parse XML string
const contents = "<TEMP_ROOT>" + p1 + "</TEMP_ROOT>";
const domParser = new dom_1.DOMParser();
const doc = domParser.parseFromString(contents, "text/xml");
/* istanbul ignore next */
if (doc.documentElement === null) {
throw new Error("Document element is null.");
}
for (const child of doc.documentElement.childNodes) {
const newChild = doc.importNode(child, true);
lastChild = XMLBuilderNodeImpl._FromNode(newChild);
this.as.node.appendChild(newChild);
}
if (lastChild === null) {
throw new Error("Could not create any elements with: " + p1.toString() + ". " + this._debugInfo());
}
return lastChild;
}
else if (util_1.isString(p1) && /^\s*[\{\[]/.test(p1)) {
// parse JSON string
const obj = JSON.parse(p1);
return this.ele(obj);
}
else if (util_1.isObject(p1)) {
// ele(obj: ExpandObject)

@@ -53,3 +80,2 @@ [namespace, name, attributes] = [undefined, p1, undefined];

}
let lastChild = null;
if (util_1.isFunction(name)) {

@@ -92,14 +118,33 @@ // evaluate if function

// cdata node
lastChild = this.dat(val);
if (util_1.isArray(val)) {
for (const item of util_1.forEachArray(val)) {
lastChild = this.dat(item);
}
}
else {
lastChild = this.dat(val);
}
}
else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.comment) === 0) {
// comment node
lastChild = this.com(val);
if (util_1.isArray(val)) {
for (const item of util_1.forEachArray(val)) {
lastChild = this.com(item);
}
}
else {
lastChild = this.com(val);
}
}
else if (!this._options.ignoreConverters && key.indexOf(this._options.convert.ins) === 0) {
// processing instruction
const insIndex = val.indexOf(' ');
const insTarget = (insIndex === -1 ? val : val.substr(0, insIndex));
const insValue = (insIndex === -1 ? '' : val.substr(insIndex + 1));
lastChild = this.ins(insTarget, insValue);
if (util_1.isString(val)) {
const insIndex = val.indexOf(' ');
const insTarget = (insIndex === -1 ? val : val.substr(0, insIndex));
const insValue = (insIndex === -1 ? '' : val.substr(insIndex + 1));
lastChild = this.ins(insTarget, insValue);
}
else {
lastChild = this.ins(val);
}
}

@@ -128,6 +173,6 @@ else if (util_1.isArray(val) && util_1.isEmpty(val)) {

// check for a namespace declaration attribute
const qName = XMLBuilderNodeImpl._algo.namespace.extractQName(key);
const qName = algorithm_1.namespace_extractQName(key);
for (const [attName, attValue] of util_1.forEachObject(val)) {
if (attName[0] === this._options.convert.att) {
const attQName = XMLBuilderNodeImpl._algo.namespace.extractQName(attName.slice(1));
const attQName = algorithm_1.namespace_extractQName(attName.slice(1));
if ((attQName[0] === null && attQName[1] === "xmlns") ||

@@ -210,2 +255,6 @@ (attQName[0] === "xmlns" && attQName[1] === qName[0])) {

}
// xmlns defaults to XMLNS namespace
if ((namespace === null || namespace === undefined) && name === "xmlns") {
namespace = infra_1.namespace.XMLNS;
}
const ele = this.as.element;

@@ -217,3 +266,3 @@ // character validation

if (namespace === undefined) {
const attQName = XMLBuilderNodeImpl._algo.namespace.extractQName(name);
const attQName = algorithm_1.namespace_extractQName(name);
if (attQName[0] === "xmlns") {

@@ -272,3 +321,3 @@ namespace = infra_1.namespace.XMLNS;

const child = this._doc.createTextNode(content);
this.as.element.appendChild(child);
this.as.node.appendChild(child);
return this;

@@ -281,3 +330,3 @@ }

const child = this._doc.createComment(content);
this.as.element.appendChild(child);
this.as.node.appendChild(child);
return this;

@@ -290,3 +339,3 @@ }

const child = this._doc.createCDATASection(content);
this.as.element.appendChild(child);
this.as.node.appendChild(child);
return this;

@@ -296,7 +345,22 @@ }

ins(target, content = '') {
// character validation
target = this._validate.insTarget(target, this._debugInfo());
content = this._validate.insValue(content, this._debugInfo());
const child = this._doc.createProcessingInstruction(target, content);
this.as.element.appendChild(child);
if (util_1.isArray(target)) {
for (const item of util_1.forEachArray(target)) {
const insIndex = item.indexOf(' ');
const insTarget = (insIndex === -1 ? item : item.substr(0, insIndex));
const insValue = (insIndex === -1 ? '' : item.substr(insIndex + 1));
this.ins(insTarget, insValue);
}
}
else if (util_1.isMap(target) || util_1.isObject(target)) {
for (const [insTarget, insValue] of util_1.forEachObject(target)) {
this.ins(insTarget, insValue);
}
}
else {
// character validation
target = this._validate.insTarget(target, this._debugInfo());
content = this._validate.insValue(content, this._debugInfo());
const child = this._doc.createProcessingInstruction(target, content);
this.as.node.appendChild(child);
}
return this;

@@ -333,3 +397,3 @@ }

const importedNode = node.as.node;
if (dom_1.util.Guard.isDocumentNode(importedNode)) {
if (util_2.Guard.isDocumentNode(importedNode)) {
// import document node

@@ -343,3 +407,3 @@ const elementNode = importedNode.documentElement;

}
else if (dom_1.util.Guard.isDocumentFragmentNode(importedNode)) {
else if (util_2.Guard.isDocumentFragmentNode(importedNode)) {
// import child nodes

@@ -411,26 +475,28 @@ for (const childNode of importedNode.childNodes) {

/** @inheritdoc */
*traverseChildren() {
for (const child of this.as.node.childNodes) {
yield XMLBuilderNodeImpl._FromNode(child);
}
forEachChild(callback, thisArg) {
this.as.node.childNodes.forEach(node => callback.call(thisArg, (XMLBuilderNodeImpl._FromNode(node))));
return this;
}
/** @inheritdoc */
*traverseAttributes() {
if (dom_1.util.Guard.isElementNode(this)) {
for (const att of this.as.element.attributes) {
yield XMLBuilderNodeImpl._FromNode(att);
}
}
forEachAttribute(callback, thisArg) {
this.as.element.attributes._attributeList.forEach(node => callback.call(thisArg, (XMLBuilderNodeImpl._FromNode(node))));
return this;
}
/** @inheritdoc */
*traverseDescendants() {
for (const node of XMLBuilderNodeImpl._algo.tree.getDescendantNodes(this.as.node, false, false)) {
yield XMLBuilderNodeImpl._FromNode(node);
forEachDescendant(callback, thisArg) {
let node = algorithm_1.tree_getFirstDescendantNode(this.as.node, false, false);
while (node !== null) {
callback.call(thisArg, (XMLBuilderNodeImpl._FromNode(node)));
node = algorithm_1.tree_getNextDescendantNode(this.as.node, node, false, false);
}
return this;
}
/** @inheritdoc */
*traverseAncestors() {
for (const node of XMLBuilderNodeImpl._algo.tree.getAncestorNodes(this.as.node, false)) {
yield XMLBuilderNodeImpl._FromNode(node);
forEachAncestor(callback, thisArg) {
let node = algorithm_1.tree_getFirstAncestorNode(this.as.node, false);
while (node !== null) {
callback.call(thisArg, (XMLBuilderNodeImpl._FromNode(node)));
node = algorithm_1.tree_getNextAncestorNode(this.as.node, node, false);
}
return this;
}

@@ -441,3 +507,3 @@ /** @inheritdoc */

if (writerOptions.format === undefined) {
writerOptions.format = "text";
writerOptions.format = "xml";
}

@@ -450,3 +516,3 @@ return this._serialize(writerOptions);

if (writerOptions.format === undefined) {
writerOptions.format = "map";
writerOptions.format = "object";
}

@@ -459,3 +525,3 @@ return this._serialize(writerOptions);

if (writerOptions.format === undefined) {
writerOptions.format = "text";
writerOptions.format = "xml";
}

@@ -470,3 +536,3 @@ return this.doc()._serialize(writerOptions);

_serialize(writerOptions) {
if (writerOptions.format === "text") {
if (writerOptions.format === "xml") {
const writer = new writers_1.StringWriterImpl(this._options);

@@ -503,3 +569,3 @@ return writer.serialize(this.as.node, writerOptions);

if (namespace === null || namespace === undefined) {
const qName = XMLBuilderNodeImpl._algo.namespace.extractQName(name);
const qName = algorithm_1.namespace_extractQName(name);
const parent = this.as.node.parentNode;

@@ -517,3 +583,3 @@ if (parent) {

else {
const attQName = XMLBuilderNodeImpl._algo.namespace.extractQName(attName);
const attQName = algorithm_1.namespace_extractQName(attName);
if (attQName[0] === "xmlns" && attQName[1] === qName[0]) {

@@ -621,3 +687,2 @@ namespace = attValue;

exports.XMLBuilderNodeImpl = XMLBuilderNodeImpl;
XMLBuilderNodeImpl._algo = new dom_1.algorithm.DOMAlgorithm();
//# sourceMappingURL=XMLBuilderNodeImpl.js.map

@@ -1,5 +0,26 @@

import * as Interfaces from './builder/interfaces';
import { XMLBuilderCreateOptions, ExpandObject, XMLBuilderNode } from './builder/interfaces';
export { Interfaces };
import { XMLBuilderCreateOptions, ExpandObject, XMLBuilderNode, WriterOptions, XMLSerializedValue } from './builder/interfaces';
/**
* Creates an XML document without any child nodes.
*
* @returns document node
*/
export declare function document(): XMLBuilderNode;
/**
* Creates an XML document without any child nodes with the given options.
*
* @param options - builder options
*
* @returns document node
*/
export declare function document(options: XMLBuilderCreateOptions): XMLBuilderNode;
/**
* Creates an XML document by parsing the given `contents`.
*
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document node
*/
export declare function document(contents: string | ExpandObject): XMLBuilderNode;
/**
* Creates an XML document.

@@ -13,4 +34,27 @@ *

*/
export declare function document(options?: XMLBuilderCreateOptions | string | ExpandObject, contents?: string | ExpandObject): XMLBuilderNode;
export declare function document(options: XMLBuilderCreateOptions, contents: string | ExpandObject): XMLBuilderNode;
/**
* Creates a new document fragment without any child nodes.
*
* @returns document fragment node
*/
export declare function fragment(): XMLBuilderNode;
/**
* Creates a new document fragment with the given options.
*
* @param options - builder options
*
* @returns document fragment node
*/
export declare function fragment(options: XMLBuilderCreateOptions): XMLBuilderNode;
/**
* Creates a new document fragment by parsing the given `contents`.
*
* @param contents - a string containing an XML fragment in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document fragment node
*/
export declare function fragment(contents: string | ExpandObject): XMLBuilderNode;
/**
* Creates a new document fragment.

@@ -24,2 +68,46 @@ *

*/
export declare function fragment(options?: XMLBuilderCreateOptions | string | ExpandObject, contents?: string | ExpandObject): XMLBuilderNode;
export declare function fragment(options: XMLBuilderCreateOptions, contents: string | ExpandObject): XMLBuilderNode;
/**
* Parses an XML document with the default options and converts it to the default
* output format.
*
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document node
*/
export declare function convert(contents: string | ExpandObject): XMLSerializedValue;
/**
* Parses an XML document with the given options and converts it to the default
* output format.
*
* @param builderOptions - builder options
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document node
*/
export declare function convert(builderOptions: XMLBuilderCreateOptions, contents: string | ExpandObject): XMLSerializedValue;
/**
* Parses an XML document with the default options and converts it to the given
* format.
*
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
* @param convertOptions - convert options
*
* @returns document node
*/
export declare function convert(contents: string | ExpandObject, convertOptions: WriterOptions): XMLSerializedValue;
/**
* Parses an XML document with the given options and converts it to the given
* format.
*
* @param builderOptions - builder options
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
* @param convertOptions - convert options
*
* @returns document node
*/
export declare function convert(builderOptions: XMLBuilderCreateOptions, contents: string | ExpandObject, convertOptions: WriterOptions): XMLSerializedValue;
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const Interfaces = __importStar(require("./builder/interfaces"));
exports.Interfaces = Interfaces;
const builder_1 = require("./builder");
const util_1 = require("@oozcitak/util");
/**
* Creates an XML document.
*
* @param options - builder options
* @param contents - a string containing an XML document in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document node
*/
function document(options, contents) {
if (options === undefined || isXMLBuilderCreateOptions(options)) {
return new builder_1.XMLBuilderImpl(options).document(contents);
/** @inheritdoc */
function document(p1, p2) {
if (p1 === undefined || isXMLBuilderCreateOptions(p1)) {
return new builder_1.XMLBuilderImpl(p1).document(p2);
}
else {
return new builder_1.XMLBuilderImpl().document(options);
return new builder_1.XMLBuilderImpl().document(p1);
}
}
exports.document = document;
/**
* Creates a new document fragment.
*
* @param options - builder options
* @param contents - a string containing an XML fragment in either XML or JSON
* format or a JS object representing nodes to insert
*
* @returns document fragment node
*/
function fragment(options, contents) {
if (options === undefined || isXMLBuilderCreateOptions(options)) {
return new builder_1.XMLBuilderImpl(options).fragment(contents);
/** @inheritdoc */
function fragment(p1, p2) {
if (p1 === undefined || isXMLBuilderCreateOptions(p1)) {
return new builder_1.XMLBuilderImpl(p1).fragment(p2);
}
else {
return new builder_1.XMLBuilderImpl().fragment(options);
return new builder_1.XMLBuilderImpl().fragment(p1);
}
}
exports.fragment = fragment;
/** @inheritdoc */
function convert(p1, p2, p3) {
let builderOptions;
let contents;
let convertOptions;
if (isXMLBuilderCreateOptions(p1) && p2 !== undefined) {
builderOptions = p1;
contents = p2;
convertOptions = p3;
}
else {
contents = p1;
convertOptions = p2;
}
return new builder_1.XMLBuilderImpl(builderOptions).document(contents).end(convertOptions);
}
exports.convert = convert;
function isXMLBuilderCreateOptions(obj) {

@@ -51,0 +43,0 @@ if (!util_1.isPlainObject(obj))

@@ -5,3 +5,2 @@ /**

export declare class Char {
private static _xmlSpec;
/**

@@ -20,3 +19,3 @@ * Escapes special characters to be used in a text node.

*/
static escapeText(str: string): string;
static escapeText(str: string, noDoubleEncoding: boolean): string;
/**

@@ -36,3 +35,3 @@ * Escapes special characters to be used in attribute values.

*/
static escapeAttrValue(str: string): string;
static escapeAttrValue(str: string, noDoubleEncoding: boolean): string;
/**

@@ -39,0 +38,0 @@ * Validates characters according to the XML spec.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const algorithm_1 = require("@oozcitak/dom/lib/algorithm");
/**

@@ -21,4 +21,5 @@ * Contains character processing utility functions.

*/
static escapeText(str) {
return str.replace(/&/g, '&amp;')
static escapeText(str, noDoubleEncoding) {
const ampRegex = noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
return str.replace(ampRegex, '&amp;')
.replace(/</g, '&lt;')

@@ -41,4 +42,5 @@ .replace(/>/g, '&gt;');

*/
static escapeAttrValue(str) {
return str.replace(/&/g, '&amp;')
static escapeAttrValue(str, noDoubleEncoding) {
const ampRegex = noDoubleEncoding ? /(?!&\S+;)&/g : /&/g;
return str.replace(ampRegex, '&amp;')
.replace(/</g, '&lt;')

@@ -56,3 +58,3 @@ .replace(/>/g, '&gt;')

static assertChar(str, version, debugInfo) {
if (!Char._xmlSpec.isLegalChar(str, version)) {
if (!algorithm_1.xml_isLegalChar(str, version)) {
throw new Error(`Invalid character in string: ${str}. ${debugInfo || ""}`);

@@ -70,3 +72,3 @@ }

Char.assertChar(str, version, debugInfo);
if (!Char._xmlSpec.isName(str)) {
if (!algorithm_1.xml_isName(str)) {
throw new Error(`Invalid character in XML name: ${str}. ${debugInfo || ""}`);

@@ -83,3 +85,3 @@ }

static assertPubId(str, version, debugInfo) {
if (!Char._xmlSpec.isPubidChar(str)) {
if (!algorithm_1.xml_isPubidChar(str)) {
throw new Error(`Invalid character in public identifier string: ${str}. ${debugInfo || ""}`);

@@ -90,3 +92,2 @@ }

exports.Char = Char;
Char._xmlSpec = new dom_1.algorithm.DOMAlgorithm().xml;
//# sourceMappingURL=Char.js.map

@@ -1,3 +0,3 @@

import { WriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { dom } from "@oozcitak/dom";
import { JSONWriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { Node } from "@oozcitak/dom/lib/dom/interfaces";
/**

@@ -20,3 +20,3 @@ * Serializes XML nodes into a JSON string.

*/
serialize(node: dom.Interfaces.Node, writerOptions?: WriterOptions): string;
serialize(node: Node, writerOptions?: JSONWriterOptions): string;
/**

@@ -23,0 +23,0 @@ * Produces an XML serialization of the given object.

@@ -33,3 +33,6 @@ "use strict";

const mapWriter = new MapWriterImpl_1.MapWriterImpl(this._builderOptions);
const obj = mapWriter.serialize(node, writerOptions);
const mapWriterOptions = util_1.applyDefaults(writerOptions, {
format: "map"
}, true);
const obj = mapWriter.serialize(node, mapWriterOptions);
return this._beginLine(options, 0) + this._serializeObject(obj, options);

@@ -36,0 +39,0 @@ }

@@ -1,5 +0,5 @@

import { WriterOptions, XMLSerializedValue, XMLBuilderOptions } from "../builder/interfaces";
import { dom, serializer } from "@oozcitak/dom";
import { XMLSerializedValue, MapWriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { Node } from "@oozcitak/dom/lib/dom/interfaces";
/**
* Serializes XML nodes into maps and arrays.
* Serializes XML nodes into ES6 maps and arrays.
*/

@@ -9,3 +9,3 @@ export declare class MapWriterImpl {

/**
* Initializes a new instance of `MapWriterImpl`.
* Initializes a new instance of `ObjectWriterImpl`.
*

@@ -21,40 +21,4 @@ * @param builderOptions - XML builder options

*/
serialize(node: dom.Interfaces.Node, writerOptions?: WriterOptions): XMLSerializedValue;
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
*/
protected _serializeNode(preNode: serializer.Interfaces.PreSerializedNode<dom.Interfaces.Node>, options: XMLBuilderOptions): XMLSerializedValue;
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
*/
private _serializeElement;
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
*/
private _serializeChildNodes;
/**
* Returns an object key for the given attribute or namespace declaration.
*
* @param name - attribute name
*/
private _getAttrKey;
/**
* Returns an object key for the given node.
*
* @param preNode - node to get a key for
*
* @returns a two-tuple whose first value is the node key and second value
* is a boolean determining whether the key can be prefixed with a random
* string to provide uniqueness.
*/
private _getNodeKey;
serialize(node: Node, writerOptions?: MapWriterOptions): XMLSerializedValue;
_convertObject(obj: XMLSerializedValue): XMLSerializedValue;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/util");
const ObjectWriterImpl_1 = require("./ObjectWriterImpl");
/**
* Serializes XML nodes into maps and arrays.
* Serializes XML nodes into ES6 maps and arrays.
*/
class MapWriterImpl {
/**
* Initializes a new instance of `MapWriterImpl`.
* Initializes a new instance of `ObjectWriterImpl`.
*

@@ -27,164 +27,31 @@ * @param builderOptions - XML builder options

});
const pre = new dom_1.serializer.PreSerializer(this._builderOptions.version);
const preNode = pre.serialize(node, false);
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
case dom_1.dom.Interfaces.NodeType.Document:
case dom_1.dom.Interfaces.NodeType.DocumentFragment:
return this._serializeNode(preNode, options);
case dom_1.dom.Interfaces.NodeType.Comment:
case dom_1.dom.Interfaces.NodeType.Text:
case dom_1.dom.Interfaces.NodeType.CData:
return new Map([[this._getNodeKey(preNode)[0],
node.data]]);
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
const pi = node;
return new Map([[this._getNodeKey(preNode)[0],
`${pi.target} ${pi.data}`]]);
/* istanbul ignore next */
default:
throw new Error("Invalid node type.");
}
// convert to object
const objectWriterOptions = util_1.applyDefaults(options, {
format: "object"
});
const objectWriter = new ObjectWriterImpl_1.ObjectWriterImpl(this._builderOptions);
const val = objectWriter.serialize(node, objectWriterOptions);
// recursively convert object into Map
return this._convertObject(val);
}
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeNode(preNode, options) {
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
return this._serializeElement(preNode, options);
case dom_1.dom.Interfaces.NodeType.Document:
return this._serializeChildNodes(preNode, options);
case dom_1.dom.Interfaces.NodeType.Comment:
return preNode.node.data;
case dom_1.dom.Interfaces.NodeType.Text:
return preNode.node.data;
case dom_1.dom.Interfaces.NodeType.DocumentFragment:
return this._serializeChildNodes(preNode, options);
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
const pi = preNode.node;
return `${pi.target} ${pi.data}`;
case dom_1.dom.Interfaces.NodeType.CData:
return preNode.node.data;
/* istanbul ignore next */
default:
throw new Error("Invalid node type.");
_convertObject(obj) {
if (util_1.isArray(obj)) {
for (let i = 0; i < obj.length; i++) {
obj[i] = this._convertObject(obj[i]);
}
return obj;
}
}
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeElement(preNode, options) {
/* istanbul ignore next */
if (preNode.name === undefined) {
throw new Error("Pre-serialized node name is null.");
else if (util_1.isObject(obj)) {
const map = new Map();
for (const key in obj) {
map.set(key, this._convertObject(obj[key]));
}
return map;
}
return new Map([
[preNode.name, this._serializeChildNodes(preNode, options)]
]);
}
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeChildNodes(preNode, options) {
const items = new Array();
const keyCount = new Map();
const keyIndices = new Map();
let hasDuplicateKeys = false;
for (const childPreNode of preNode.children) {
if (childPreNode.node.nodeType === dom_1.dom.Interfaces.NodeType.DocumentType)
continue;
const [key, canIncrement] = this._getNodeKey(childPreNode);
items.push([key, canIncrement, childPreNode]);
let count = keyCount.get(key);
count = (count || 0) + 1;
if (!hasDuplicateKeys && !canIncrement && count > 1)
[
hasDuplicateKeys = true
];
keyCount.set(key, count);
keyIndices.set(key, 0);
}
if (items.length === 1 && preNode.attributes.length === 0 && dom_1.util.Guard.isTextNode(items[0][2].node)) {
// an element node with a single text node
return items[0][2].node.data;
}
else {
const markup = new Map();
for (const attr of preNode.attributes) {
const key = this._getAttrKey(attr.name);
markup.set(key, attr.value);
}
for (const [key, canIncrement, node] of items) {
// serialize child nodes or node contents
const nodeResult = node.node.nodeType === dom_1.dom.Interfaces.NodeType.Element ?
this._serializeChildNodes(node, options) :
this._serializeNode(node, options);
if (canIncrement && keyCount.get(key) > 1) {
// generate a unique key
let index = (keyIndices.get(key) || 0) + 1;
const uniqueKey = key + index.toString();
keyIndices.set(key, index);
markup.set(uniqueKey, nodeResult);
}
else if (keyCount.get(key) > 1) {
// cannot generate a unique key, create an array to hold nodes with
// duplicate keys
const nodeList = (markup.get(key) || []);
nodeList.push(nodeResult);
markup.set(key, nodeList);
}
else {
// object already has a unique key
markup.set(key, nodeResult);
}
}
return markup;
return obj;
}
}
/**
* Returns an object key for the given attribute or namespace declaration.
*
* @param name - attribute name
*/
_getAttrKey(name) {
return this._builderOptions.convert.att + name;
}
/**
* Returns an object key for the given node.
*
* @param preNode - node to get a key for
*
* @returns a two-tuple whose first value is the node key and second value
* is a boolean determining whether the key can be prefixed with a random
* string to provide uniqueness.
*/
_getNodeKey(preNode) {
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
return [preNode.node.tagName, false];
case dom_1.dom.Interfaces.NodeType.Comment:
return [this._builderOptions.convert.comment, true];
case dom_1.dom.Interfaces.NodeType.Text:
return [this._builderOptions.convert.text, true];
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
return [this._builderOptions.convert.ins, true];
case dom_1.dom.Interfaces.NodeType.CData:
return [this._builderOptions.convert.cdata, true];
/* istanbul ignore next */
default:
throw new Error("Invalid node type.");
}
}
}
exports.MapWriterImpl = MapWriterImpl;
//# sourceMappingURL=MapWriterImpl.js.map

@@ -1,3 +0,3 @@

import { WriterOptions, XMLSerializedValue, XMLBuilderOptions } from "../builder/interfaces";
import { dom, serializer } from "@oozcitak/dom";
import { XMLSerializedValue, ObjectWriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { Node } from "@oozcitak/dom/lib/dom/interfaces";
/**

@@ -20,40 +20,26 @@ * Serializes XML nodes into objects and arrays.

*/
serialize(node: dom.Interfaces.Node, writerOptions?: WriterOptions): XMLSerializedValue;
serialize(node: Node, writerOptions?: ObjectWriterOptions): XMLSerializedValue;
private _process;
private _addAttr;
private _addText;
private _addComment;
private _addInstruction;
private _addCDATA;
private _addElement;
private _isAttrNode;
private _isTextNode;
private _isCommentNode;
private _isInstructionNode;
private _isCDATANode;
private _isElementNode;
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
* Returns an object key for an attribute or namespace declaration.
*/
protected _serializeNode(preNode: serializer.Interfaces.PreSerializedNode<dom.Interfaces.Node>, options: XMLBuilderOptions): XMLSerializedValue;
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
*/
private _serializeElement;
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
*/
private _serializeChildNodes;
/**
* Returns an object key for the given attribute or namespace declaration.
*
* @param name - attribute name
*/
private _getAttrKey;
/**
* Returns an object key for the given node.
* Returns an object key for the given node type.
*
* @param preNode - node to get a key for
*
* @returns a two-tuple whose first value is the node key and second value
* is a boolean determining whether the key can be prefixed with a random
* string to provide uniqueness.
* @param nodeType - node type to get a key for
*/
private _getNodeKey;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/util");
const interfaces_1 = require("@oozcitak/dom/lib/dom/interfaces");
const PreSerializer_1 = require("@oozcitak/dom/lib/serializer/PreSerializer");
/**

@@ -27,157 +28,388 @@ * Serializes XML nodes into objects and arrays.

});
const pre = new dom_1.serializer.PreSerializer(this._builderOptions.version);
const preNode = pre.serialize(node, false);
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
case dom_1.dom.Interfaces.NodeType.Document:
case dom_1.dom.Interfaces.NodeType.DocumentFragment:
return this._serializeNode(preNode, options);
case dom_1.dom.Interfaces.NodeType.Comment:
case dom_1.dom.Interfaces.NodeType.Text:
case dom_1.dom.Interfaces.NodeType.CData:
return new Map([[this._getNodeKey(preNode)[0],
node.data]]);
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
const pi = node;
return new Map([[this._getNodeKey(preNode)[0],
`${pi.target} ${pi.data}`]]);
/* istanbul ignore next */
default:
throw new Error("Invalid node type.");
let currentList = [];
let currentIndex = 0;
let listRegister = [currentList];
const pre = new PreSerializer_1.PreSerializer(this._builderOptions.version, {
beginElement: (name) => {
const childItems = this._addElement(currentList, name);
currentIndex++;
if (listRegister.length > currentIndex) {
listRegister[currentIndex] = childItems;
}
else {
listRegister.push(childItems);
}
currentList = childItems;
},
endElement: () => {
currentList = listRegister[--currentIndex];
},
attribute: (name, value) => {
this._addAttr(currentList, name, value);
},
comment: (data) => {
this._addComment(currentList, data);
},
text: (data) => {
this._addText(currentList, data);
},
instruction: (target, data) => {
this._addInstruction(currentList, target + " " + data);
},
cdata: (data) => {
this._addCDATA(currentList, data);
}
});
/**
* First pass, serialize nodes
* This creates a list of nodes grouped under node types while preserving
* insertion order. For example:
* [
* root: [
* node: [
* { "@" : { "att1": "val1", "att2": "val2" }
* { "#": "node text" }
* { childNode: [] }
* { "#": "more text" }
* ],
* node: [
* { "@" : { "att": "val" }
* { "#": [ "text line1", "text line2" ] }
* ]
* ]
* ]
*/
pre.serialize(node, false);
/**
* Second pass, process node lists. Above example becomes:
* {
* root: {
* node: [
* {
* "@att1": "val1",
* "@att2": "val2",
* "#1": "node text",
* childNode: {},
* "#2": "more text"
* },
* {
* "@att": "val",
* "#": [ "text line1", "text line2" ]
* }
* ]
* }
* }
*/
return this._process(currentList);
}
_process(items) {
if (items.length === 0)
return {};
// determine if there are non-unique element names
const namesSeen = {};
let hasNonUniqueNames = false;
let textCount = 0;
let commentCount = 0;
let instructionCount = 0;
let cdataCount = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
const key = Object.keys(item)[0];
switch (key) {
case "@":
continue;
case "#":
textCount++;
break;
case "!":
commentCount++;
break;
case "?":
instructionCount++;
break;
case "$":
cdataCount++;
break;
default:
if (namesSeen[key]) {
hasNonUniqueNames = true;
}
else {
namesSeen[key] = true;
}
break;
}
}
if (textCount === 1 && items.length === 1 && util_1.isString(items[0]["#"])) {
// special case of an element node with a single text node
return items[0]["#"];
}
else if (hasNonUniqueNames) {
// list contains element nodes with non-unique names
// return an array with mixed content notation
const result = [];
const obj = { "#": result };
for (let i = 0; i < items.length; i++) {
const item = items[i];
const key = Object.keys(item)[0];
switch (key) {
case "@":
const attrs = item["@"];
const attrKeys = Object.keys(attrs);
if (attrKeys.length === 1) {
result.push({ [this._getAttrKey() + attrKeys[0]]: attrs[attrKeys[0]] });
}
else {
result.push({ [this._getAttrKey()]: item["@"] });
}
break;
case "#":
const textKey = this._getNodeKey(interfaces_1.NodeType.Text);
result.push({ [textKey]: item["#"] });
break;
case "!":
const commentKey = this._getNodeKey(interfaces_1.NodeType.Comment);
result.push({ [commentKey]: item["!"] });
break;
case "?":
const instructionKey = this._getNodeKey(interfaces_1.NodeType.ProcessingInstruction);
result.push({ [instructionKey]: item["?"] });
break;
case "$":
const cdataKey = this._getNodeKey(interfaces_1.NodeType.CData);
result.push({ [cdataKey]: item["$"] });
break;
default:
// element node
const ele = item;
if (ele[key].length !== 0 && util_1.isArray(ele[key][0])) {
// group of element nodes
const eleGroup = [];
const listOfLists = ele[key];
for (let i = 0; i < listOfLists.length; i++) {
eleGroup.push(this._process(listOfLists[i]));
}
result.push({ [key]: eleGroup });
}
else {
// single element node
result.push({ [key]: this._process(ele[key]) });
}
break;
}
}
return obj;
}
else {
// all element nodes have unique names
// return an object while prefixing data node keys
let textId = 1;
let commentId = 1;
let instructionId = 1;
let cdataId = 1;
const obj = {};
for (let i = 0; i < items.length; i++) {
const item = items[i];
const key = Object.keys(item)[0];
switch (key) {
case "@":
const attrs = item["@"];
const attrKeys = Object.keys(attrs);
if (attrKeys.length === 1) {
obj[this._getAttrKey() + attrKeys[0]] = attrs[attrKeys[0]];
}
else {
obj[this._getAttrKey()] = item["@"];
}
break;
case "#":
const textKey = textCount > 1 ? this._getNodeKey(interfaces_1.NodeType.Text) + (textId++).toString() : this._getNodeKey(interfaces_1.NodeType.Text);
obj[textKey] = item["#"];
break;
case "!":
const commentKey = commentCount > 1 ? this._getNodeKey(interfaces_1.NodeType.Comment) + (commentId++).toString() : this._getNodeKey(interfaces_1.NodeType.Comment);
obj[commentKey] = item["!"];
break;
case "?":
const instructionKey = instructionCount > 1 ? this._getNodeKey(interfaces_1.NodeType.ProcessingInstruction) + (instructionId++).toString() : this._getNodeKey(interfaces_1.NodeType.ProcessingInstruction);
obj[instructionKey] = item["?"];
break;
case "$":
const cdataKey = cdataCount > 1 ? this._getNodeKey(interfaces_1.NodeType.CData) + (cdataId++).toString() : this._getNodeKey(interfaces_1.NodeType.CData);
obj[cdataKey] = item["$"];
break;
default:
// element node
const ele = item;
if (ele[key].length !== 0 && util_1.isArray(ele[key][0])) {
// group of element nodes
const eleGroup = [];
const listOfLists = ele[key];
for (let i = 0; i < listOfLists.length; i++) {
eleGroup.push(this._process(listOfLists[i]));
}
obj[key] = eleGroup;
}
else {
// single element node
obj[key] = this._process(ele[key]);
}
break;
}
}
return obj;
}
}
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeNode(preNode, options) {
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
return this._serializeElement(preNode, options);
case dom_1.dom.Interfaces.NodeType.Document:
return this._serializeChildNodes(preNode, options);
case dom_1.dom.Interfaces.NodeType.Comment:
return preNode.node.data;
case dom_1.dom.Interfaces.NodeType.Text:
return preNode.node.data;
case dom_1.dom.Interfaces.NodeType.DocumentFragment:
return this._serializeChildNodes(preNode, options);
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
const pi = preNode.node;
return `${pi.target} ${pi.data}`;
case dom_1.dom.Interfaces.NodeType.CData:
return preNode.node.data;
/* istanbul ignore next */
default:
throw new Error("Invalid node type.");
_addAttr(items, name, value) {
if (items.length === 0) {
items.push({ "@": { [name]: value } });
}
else {
const lastItem = items[items.length - 1];
/* istanbul ignore else */
if (this._isAttrNode(lastItem)) {
lastItem["@"][name] = value;
}
else {
items.push({ "@": { [name]: value } });
}
}
}
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeElement(preNode, options) {
/* istanbul ignore next */
if (preNode.name === undefined) {
throw new Error("Pre-serialized node name is undefined.");
_addText(items, value) {
if (items.length === 0) {
items.push({ "#": value });
}
const markup = {};
markup[preNode.name] = this._serializeChildNodes(preNode, options);
return markup;
else {
const lastItem = items[items.length - 1];
if (this._isTextNode(lastItem)) {
if (util_1.isArray(lastItem["#"])) {
lastItem["#"].push(value);
}
else {
lastItem["#"] = [lastItem["#"], value];
}
}
else {
items.push({ "#": value });
}
}
}
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
*/
_serializeChildNodes(preNode, options) {
const items = new Array();
const keyCount = new Map();
const keyIndices = new Map();
let hasDuplicateKeys = false;
for (const childPreNode of preNode.children) {
if (childPreNode.node.nodeType === dom_1.dom.Interfaces.NodeType.DocumentType)
continue;
const [key, canIncrement] = this._getNodeKey(childPreNode);
items.push([key, canIncrement, childPreNode]);
let count = keyCount.get(key);
count = (count || 0) + 1;
if (!hasDuplicateKeys && !canIncrement && count > 1)
[
hasDuplicateKeys = true
];
keyCount.set(key, count);
keyIndices.set(key, 0);
_addComment(items, value) {
if (items.length === 0) {
items.push({ "!": value });
}
if (items.length === 1 && preNode.attributes.length === 0 && dom_1.util.Guard.isTextNode(items[0][2].node)) {
// an element node with a single text node
return items[0][2].node.data;
else {
const lastItem = items[items.length - 1];
if (this._isCommentNode(lastItem)) {
if (util_1.isArray(lastItem["!"])) {
lastItem["!"].push(value);
}
else {
lastItem["!"] = [lastItem["!"], value];
}
}
else {
items.push({ "!": value });
}
}
}
_addInstruction(items, value) {
if (items.length === 0) {
items.push({ "?": value });
}
else {
const markup = {};
for (const attr of preNode.attributes) {
const key = this._getAttrKey(attr.name);
markup[key] = attr.value;
const lastItem = items[items.length - 1];
if (this._isInstructionNode(lastItem)) {
if (util_1.isArray(lastItem["?"])) {
lastItem["?"].push(value);
}
else {
lastItem["?"] = [lastItem["?"], value];
}
}
for (const [key, canIncrement, node] of items) {
// serialize child nodes or node contents
const nodeResult = node.node.nodeType === dom_1.dom.Interfaces.NodeType.Element ?
this._serializeChildNodes(node, options) :
this._serializeNode(node, options);
if (canIncrement && keyCount.get(key) > 1) {
// generate a unique key
let index = (keyIndices.get(key) || 0) + 1;
const uniqueKey = key + index.toString();
keyIndices.set(key, index);
markup[uniqueKey] = nodeResult;
else {
items.push({ "?": value });
}
}
}
_addCDATA(items, value) {
if (items.length === 0) {
items.push({ "$": value });
}
else {
const lastItem = items[items.length - 1];
if (this._isCDATANode(lastItem)) {
if (util_1.isArray(lastItem["$"])) {
lastItem["$"].push(value);
}
else if (keyCount.get(key) > 1) {
// cannot generate a unique key, create an array to hold nodes with
// duplicate keys
const nodeList = (markup[key] || []);
nodeList.push(nodeResult);
markup[key] = nodeList;
else {
lastItem["$"] = [lastItem["$"], value];
}
}
else {
items.push({ "$": value });
}
}
}
_addElement(items, name) {
const childItems = [];
if (items.length === 0) {
items.push({ [name]: childItems });
}
else {
const lastItem = items[items.length - 1];
if (this._isElementNode(lastItem, name)) {
if (lastItem[name].length !== 0 && util_1.isArray(lastItem[name][0])) {
const listOfLists = lastItem[name];
listOfLists.push(childItems);
}
else {
// object already has a unique key
markup[key] = nodeResult;
lastItem[name] = [lastItem[name], childItems];
}
}
return markup;
else {
items.push({ [name]: childItems });
}
}
return childItems;
}
_isAttrNode(x) {
return "@" in x;
}
_isTextNode(x) {
return "#" in x;
}
_isCommentNode(x) {
return "!" in x;
}
_isInstructionNode(x) {
return "?" in x;
}
_isCDATANode(x) {
return "$" in x;
}
_isElementNode(x, name) {
return name in x;
}
/**
* Returns an object key for the given attribute or namespace declaration.
*
* @param name - attribute name
* Returns an object key for an attribute or namespace declaration.
*/
_getAttrKey(name) {
return this._builderOptions.convert.att + name;
_getAttrKey() {
return this._builderOptions.convert.att;
}
/**
* Returns an object key for the given node.
* Returns an object key for the given node type.
*
* @param preNode - node to get a key for
*
* @returns a two-tuple whose first value is the node key and second value
* is a boolean determining whether the key can be prefixed with a random
* string to provide uniqueness.
* @param nodeType - node type to get a key for
*/
_getNodeKey(preNode) {
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
return [preNode.node.tagName, false];
case dom_1.dom.Interfaces.NodeType.Comment:
return [this._builderOptions.convert.comment, true];
case dom_1.dom.Interfaces.NodeType.Text:
return [this._builderOptions.convert.text, true];
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
return [this._builderOptions.convert.ins, true];
case dom_1.dom.Interfaces.NodeType.CData:
return [this._builderOptions.convert.cdata, true];
_getNodeKey(nodeType) {
switch (nodeType) {
case interfaces_1.NodeType.Comment:
return this._builderOptions.convert.comment;
case interfaces_1.NodeType.Text:
return this._builderOptions.convert.text;
case interfaces_1.NodeType.ProcessingInstruction:
return this._builderOptions.convert.ins;
case interfaces_1.NodeType.CData:
return this._builderOptions.convert.cdata;
/* istanbul ignore next */

@@ -184,0 +416,0 @@ default:

@@ -1,3 +0,3 @@

import { WriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { dom } from "@oozcitak/dom";
import { StringWriterOptions, XMLBuilderOptions } from "../builder/interfaces";
import { Node } from "@oozcitak/dom/lib/dom/interfaces";
/**

@@ -8,2 +8,5 @@ * Serializes XML nodes into strings.

private _builderOptions;
private _options;
private _refs;
private _pre;
/**

@@ -21,106 +24,42 @@ * Initializes a new instance of `StringWriterImpl`.

*/
serialize(node: dom.Interfaces.Node, writerOptions?: WriterOptions): string;
serialize(node: Node, writerOptions?: StringWriterOptions): string;
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a document type node.
*/
private _serializeNode;
private _docType;
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the beginning of the opening tag of an element node.
*/
private _serializeChildNodes;
private _openTagBegin;
/**
* Produces an XML serialization of the given node's attributes.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the ending of the opening tag of an element node.
*/
private _serializeAttributes;
private _openTagEnd;
/**
* Produces an XML serialization of a document node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the closing tag of an element node.
*/
private _serializeDocument;
private _closeTag;
/**
* Produces an XML serialization of a document type node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of an attribute node.
*/
private _serializeDocumentType;
private _attribute;
/**
* Produces an XML serialization of a document fragment node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a text node.
*/
private _serializeDocumentFragment;
private _text;
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a cdata section node.
*/
private _serializeElement;
private _cdata;
/**
* Produces an XML serialization of a text node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a comment node.
*/
private _serializeText;
private _comment;
/**
* Produces an XML serialization of a CDATA node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a processing instruction node.
*/
private _serializeCdata;
private _instruction;
/**
* Produces an XML serialization of a comment node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
private _serializeComment;
/**
* Produces an XML serialization of a processing instruction node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
private _serializeProcessingInstruction;
/**
* Produces an XML serialization of an attribute.
*
* @param preAttr - current attribute
* @param options - serialization options
* @param refs - reference parameters
*/
private _serializeAttribute;
/**
* Produces characters to be prepended to a line of string in pretty-print
* mode.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/

@@ -131,8 +70,4 @@ private _beginLine;

* mode.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
private _endLine;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_1 = require("@oozcitak/dom");
const util_1 = require("@oozcitak/util");
const interfaces_1 = require("@oozcitak/dom/lib/dom/interfaces");
const util_2 = require("@oozcitak/dom/lib/util");
const PreSerializer_1 = require("@oozcitak/dom/lib/serializer/PreSerializer");
const validator_1 = require("../validator");

@@ -26,7 +28,7 @@ /**

// provide default options
const options = util_1.applyDefaults(writerOptions, {
this._options = util_1.applyDefaults(writerOptions, {
headless: false,
prettyPrint: false,
indent: ' ',
newline: '\n',
indent: " ",
newline: "\n",
offset: 0,

@@ -39,246 +41,155 @@ width: 80,

});
const pre = new dom_1.serializer.PreSerializer(this._builderOptions.version);
let markup = this._serializeNode(pre.serialize(node, false), options, { suppressPrettyCount: 0 });
// remove trailing newline
if (options.prettyPrint && markup.slice(-options.newline.length) === options.newline) {
markup = markup.slice(0, -options.newline.length);
}
return markup;
}
/**
* Produces an XML serialization of the given node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_serializeNode(preNode, options, refs) {
switch (preNode.node.nodeType) {
case dom_1.dom.Interfaces.NodeType.Element:
return this._serializeElement(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.Document:
return this._serializeDocument(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.Comment:
return this._serializeComment(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.Text:
return this._serializeText(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.DocumentFragment:
return this._serializeDocumentFragment(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.DocumentType:
return this._serializeDocumentType(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.ProcessingInstruction:
return this._serializeProcessingInstruction(preNode, options, refs);
case dom_1.dom.Interfaces.NodeType.CData:
return this._serializeCdata(preNode, options, refs);
default:
throw new Error("Invalid node type.");
}
}
/**
* Produces an XML serialization of the given node's children.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_serializeChildNodes(preNode, options, refs) {
let markup = '';
for (const child of preNode.children) {
markup += this._serializeNode(child, options, refs);
}
return markup;
}
/**
* Produces an XML serialization of the given node's attributes.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_serializeAttributes(preNode, options, refs) {
let markup = '';
for (const preAttr of preNode.attributes) {
markup += ` ${this._serializeAttribute(preAttr, options, refs)}`;
}
return markup;
}
/**
* Produces an XML serialization of a document node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_serializeDocument(preNode, options, refs) {
let markup = '';
if (!options.headless) {
markup = `${this._beginLine(preNode, options, refs)}<?xml`;
markup += ` version="${this._builderOptions.version}"`;
this._refs = { suppressPretty: false, emptyNode: false, markup: "" };
this._pre = new PreSerializer_1.PreSerializer(this._builderOptions.version, {
docType: this._docType.bind(this),
openTagBegin: this._openTagBegin.bind(this),
openTagEnd: this._openTagEnd.bind(this),
closeTag: this._closeTag.bind(this),
attribute: this._attribute.bind(this),
comment: this._comment.bind(this),
text: this._text.bind(this),
instruction: this._instruction.bind(this),
cdata: this._cdata.bind(this)
});
// XML declaration
if (node.nodeType === interfaces_1.NodeType.Document && !this._options.headless) {
this._beginLine();
this._refs.markup = "<?xml";
this._refs.markup += " version=\"" + this._builderOptions.version + "\"";
if (this._builderOptions.encoding !== undefined) {
markup += ` encoding="${this._builderOptions.encoding}"`;
this._refs.markup += " encoding=\"" + this._builderOptions.encoding + "\"";
}
if (this._builderOptions.standalone !== undefined) {
markup += ` standalone="${this._builderOptions.standalone ? "yes" : "no"}"`;
this._refs.markup += " standalone=\"" + (this._builderOptions.standalone ? "yes" : "no") + "\"";
}
markup += `?>${this._endLine(preNode, options, refs)}`;
this._refs.markup += "?>";
this._endLine();
}
markup += this._serializeChildNodes(preNode, options, refs);
return markup;
this._pre.serialize(node, false);
// remove trailing newline
if (this._options.prettyPrint &&
this._refs.markup.slice(-this._options.newline.length) === this._options.newline) {
this._refs.markup = this._refs.markup.slice(0, -this._options.newline.length);
}
return this._refs.markup;
}
/**
* Produces an XML serialization of a document type node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a document type node.
*/
_serializeDocumentType(preNode, options, refs) {
let markup = this._beginLine(preNode, options, refs);
if (preNode.node.publicId && preNode.node.systemId) {
markup += `<!DOCTYPE ${preNode.node.name} PUBLIC "${preNode.node.publicId}" "${preNode.node.systemId}">`;
_docType(name, publicId, systemId) {
this._beginLine();
if (publicId && systemId) {
this._refs.markup += "<!DOCTYPE " + name + " PUBLIC \"" + publicId + "\" \"" + systemId + "\">";
}
else if (preNode.node.publicId) {
markup += `<!DOCTYPE ${preNode.node.name} PUBLIC "${preNode.node.publicId}">`;
else if (publicId) {
this._refs.markup += "<!DOCTYPE " + name + " PUBLIC \"" + publicId + "\">";
}
else if (preNode.node.systemId) {
markup += `<!DOCTYPE ${preNode.node.name} SYSTEM "${preNode.node.systemId}">`;
else if (systemId) {
this._refs.markup += "<!DOCTYPE " + name + " SYSTEM \"" + systemId + "\">";
}
else {
markup += `<!DOCTYPE ${preNode.node.name}>`;
this._refs.markup += "<!DOCTYPE " + name + ">";
}
markup += this._endLine(preNode, options, refs);
return markup;
this._endLine();
}
/**
* Produces an XML serialization of a document fragment node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the beginning of the opening tag of an element node.
*/
_serializeDocumentFragment(preNode, options, refs) {
return this._serializeChildNodes(preNode, options, refs);
_openTagBegin(name) {
this._beginLine();
this._refs.markup += "<" + name;
}
/**
* Produces an XML serialization of an element node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the ending of the opening tag of an element node.
*/
_serializeElement(preNode, options, refs) {
// opening tag
let markup = this._beginLine(preNode, options, refs) + '<' + preNode.name;
// serialize attributes
markup += this._serializeAttributes(preNode, options, refs);
let textOnlyNode = true;
let emptyNode = true;
for (const childNode of preNode.children) {
if (!dom_1.util.Guard.isTextNode(childNode.node)) {
textOnlyNode = false;
emptyNode = false;
break;
}
else if (childNode.node.data !== '') {
emptyNode = false;
}
}
if (emptyNode) {
// self closing tag
if (options.allowEmptyTags) {
markup += `></${preNode.name}>${this._endLine(preNode, options, refs)}`;
}
else {
if (options.spaceBeforeSlash) {
markup += ' ';
_openTagEnd(name, selfClosing, voidElement) {
// do not indent text only elements or elements with empty text nodes
this._refs.suppressPretty = false;
this._refs.emptyNode = false;
if (this._options.prettyPrint && !selfClosing && !voidElement && !this._options.indentTextOnlyNodes) {
let textOnlyNode = true;
let emptyNode = true;
for (const childNode of this._pre.currentNode.childNodes) {
if (!util_2.Guard.isTextNode(childNode)) {
textOnlyNode = false;
emptyNode = false;
break;
}
markup += `/>${this._endLine(preNode, options, refs)}`;
else if (childNode.data !== '') {
emptyNode = false;
}
}
this._refs.suppressPretty = textOnlyNode;
this._refs.emptyNode = emptyNode;
}
if ((voidElement || selfClosing) && this._options.allowEmptyTags) {
this._refs.markup += "></" + name + ">";
}
else {
// an element node with only text child nodes
let prettySuppressed = false;
if (options.prettyPrint && textOnlyNode && !options.indentTextOnlyNodes) {
refs.suppressPrettyCount++;
prettySuppressed = true;
}
markup += `>${this._endLine(preNode, options, refs)}`;
// serialize child-nodes
markup += this._serializeChildNodes(preNode, options, refs);
// closing tag
markup += `${this._beginLine(preNode, options, refs)}</${preNode.name}>`;
if (prettySuppressed) {
refs.suppressPrettyCount--;
}
markup += `${this._endLine(preNode, options, refs)}`;
this._refs.markup += voidElement ? " />" :
(selfClosing || this._refs.emptyNode) ? (this._options.spaceBeforeSlash ? " />" : "/>") : ">";
}
return markup;
this._endLine();
}
/**
* Produces an XML serialization of a text node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of the closing tag of an element node.
*/
_serializeText(preNode, options, refs) {
return this._beginLine(preNode, options, refs) +
validator_1.Char.escapeText(preNode.node.data) +
this._endLine(preNode, options, refs);
_closeTag(name) {
if (!this._refs.emptyNode) {
this._beginLine();
this._refs.markup += "</" + name + ">";
}
this._refs.suppressPretty = false;
this._refs.emptyNode = false;
this._endLine();
}
/**
* Produces an XML serialization of a CDATA node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of an attribute node.
*/
_serializeCdata(preNode, options, refs) {
return `${this._beginLine(preNode, options, refs)}<![CDATA[${preNode.node.data}]]>${this._endLine(preNode, options, refs)}`;
_attribute(name, value) {
this._refs.markup += " " + name + "=\"" + validator_1.Char.escapeAttrValue(value, this._options.noDoubleEncoding) + "\"";
}
/**
* Produces an XML serialization of a comment node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a text node.
*/
_serializeComment(preNode, options, refs) {
return `${this._beginLine(preNode, options, refs)}<!--${preNode.node.data}-->${this._endLine(preNode, options, refs)}`;
_text(data) {
this._beginLine();
this._refs.markup += validator_1.Char.escapeText(data, this._options.noDoubleEncoding);
this._endLine();
}
/**
* Produces an XML serialization of a processing instruction node.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a cdata section node.
*/
_serializeProcessingInstruction(preNode, options, refs) {
return `${this._beginLine(preNode, options, refs)}<?${preNode.node.target} ${preNode.node.data}?>${this._endLine(preNode, options, refs)}`;
_cdata(data) {
this._beginLine();
this._refs.markup += "<![CDATA[" + data + "]]>";
this._endLine();
}
/**
* Produces an XML serialization of an attribute.
*
* @param preAttr - current attribute
* @param options - serialization options
* @param refs - reference parameters
* Produces the serialization of a comment node.
*/
_serializeAttribute(preAttr, options, refs) {
return `${preAttr.name}="${validator_1.Char.escapeAttrValue(preAttr.value)}"`;
_comment(data) {
this._beginLine();
this._refs.markup += "<!--" + data + "-->";
this._endLine();
}
/**
* Produces the serialization of a processing instruction node.
*/
_instruction(target, data) {
this._beginLine();
this._refs.markup += "<?" + target + " " + data + "?>";
this._endLine();
}
/**
* Produces characters to be prepended to a line of string in pretty-print
* mode.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_beginLine(preNode, options, refs) {
if (!options.prettyPrint || refs.suppressPrettyCount > 0) {
return '';
_beginLine() {
if (!this._options.prettyPrint || this._refs.suppressPretty) {
return;
}
else {
const indentLevel = options.offset + preNode.level + 1;
return indentLevel > 0 ? new Array(indentLevel).join(options.indent) : '';
const indentLevel = this._options.offset + this._pre.level + 1;
this._refs.markup += indentLevel > 0 ? new Array(indentLevel).join(this._options.indent) : '';
}

@@ -289,13 +200,9 @@ }

* mode.
*
* @param preNode - current node
* @param options - serialization options
* @param refs - reference parameters
*/
_endLine(preNode, options, refs) {
if (!options.prettyPrint || refs.suppressPrettyCount > 0) {
return '';
_endLine() {
if (!this._options.prettyPrint || this._refs.suppressPretty) {
return;
}
else {
return options.newline;
this._refs.markup += this._options.newline;
}

@@ -302,0 +209,0 @@ }

{
"name": "xmlbuilder2",
"version": "0.0.4",
"version": "0.0.7",
"keywords": [

@@ -28,7 +28,12 @@ "xml",

"dependencies": {
"@oozcitak/util": "1.0.3",
"@oozcitak/dom": "0.0.11",
"@oozcitak/util": "4.0.0",
"@oozcitak/dom": "1.7.1",
"@oozcitak/infra": "1.0.4"
},
"devDependencies": {
"@types/node": "*",
"@types/jest": "*",
"@types/dedent": "*",
"@types/benchmark": "*",
"@types/chalk": "*",
"typescript": "*",

@@ -39,5 +44,7 @@ "jest": "*",

"glob": "*",
"@types/node": "*",
"@types/jest": "*",
"@types/dedent": "*"
"xpath": "*",
"xmlbuilder": "*",
"ts-node": "*",
"benchmark": "*",
"chalk": "*"
},

@@ -56,4 +63,6 @@ "jest": {

"compile": "rm -rf ./lib && tsc --version && tsc",
"test": "npm run compile && jest --coverage"
"test": "npm run compile && jest --coverage",
"perf": "npm run compile && ts-node ./perf/perf.ts",
"publish-public": "npm run test && npm publish"
}
}

@@ -22,3 +22,3 @@ # xmlbuilder2

``` js
import { document } from 'xmlbuilder2';
const { document } = require('xmlbuilder2');

@@ -36,3 +36,3 @@ const root = document()

.up()
.up()
.up();

@@ -64,3 +64,3 @@ // convert the XML tree to string

``` js
import { document } from 'xmlbuilder2';
const { document } = require('xmlbuilder2');

@@ -90,5 +90,5 @@ const obj = {

```js
import { document } from 'xmlbuilder2';
const { document } = require('xmlbuilder2');
const xmlStr = '<root att="val"><foo/><bar>foobar</bar></foo></root>';
const xmlStr = '<root att="val"><foo><bar>foobar</bar></foo></root>';
const doc = document(xmlStr);

@@ -106,3 +106,3 @@

<root att="val">
<foo/>
<foo>
<bar>foobar</bar>

@@ -116,2 +116,3 @@ </foo>

const obj = doc.end({ format: "object" });
console.log(obj);
```

@@ -121,7 +122,7 @@ ```js

root: {
"@att": "val",
"foo": {
"bar": "foobar"
}
"baz": {}
'@att': 'val',
foo: {
bar: 'foobar'
},
baz: {}
}

@@ -135,3 +136,3 @@ }

``` js
import { document } from 'xmlbuilder2';
const { document } = require('xmlbuilder2');

@@ -143,3 +144,3 @@ const root = document().ele('squares');

const item = root.ele('data');
item.att('x', i;
item.att('x', i);
item.att('y', i * i);

@@ -146,0 +147,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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