@isopodlabs/xml v1.1.0
@isopodlabs/xml
This package provides a complete solution for working with XML in TypeScript. It allows you to create, manipulate, and parse XML documents easily, and can parse html with appropriate options.
Why
- Self Conatained
- Fast
- Simple
Installation
To install the package, use npm:
npm install @isopodlabs/packageImporting the Package
import * as xml from 'xml';Loading XML
const xmlString = `<root><child>Text</child></root>`;
const rootElement = xml.parse(xmlString);parse takes an optional options parameter:
export interface InputOptions {
entities?: Entities,
allowUnclosed?: RegExp,
allowAttributeWithoutValue?: boolean,
allowNonQuotedAttribute?: boolean,
}entities: By default onlyamp,gt,lt, andquotentities are recognised. This option allows additional entities to be recognised.allowUnclosed: Allows tags that match this RegExp to omit their closing tag.allowAttributeWithoutValue: Allows attributes without the ="\<value>" part.allowNonQuotedAttribute: Allows attributes to be unquoted.
Writing XML
const xmlString = rootElement.toString();toString takes an optional options parameter:
export interface OutputOptions {
newline?: string,
indent?: string,
afteratt?: string,
entities?: Entities,
}newline: what to print after each element. Default is '\n'indent: what to prepend to newline for each nested level of elements. Default is ' ' (two spaces)afteratt: what to print after the list of attributes. Default is '' (nothing)entities: additional entities to use when outputting text. Default uses onlyamp,gt, andlt(andquotinside attributes).
Element
Represents an XML element.
class Element {
//properties
name: string;
attributes: Attributes;
children: Node[];
next?: Element;
parent?: Element;
//creation
constructor(name: string, attributes?: Attributes, children?: Node[]);
add(e: Node): void;
remove(e: Node): boolean;
setText(text: string): void;
//child access
get elements(): Record<string, Element>;
firstElement(): Element | undefined;
allElements(): Element[];
firstText(): string | undefined;
allText(): string[];
//output
toString(options?: OutputOptions): string;
setOptions(options: OutputOptions): this;
}
//example
const element = new xml.Element("root", { attr: "value" }, [
new Comment("Child comment"),
"some text",
new xml.Element("Child"),
new CDATA("Child CDATA"),
]);Node
A xml.Node is a child of an Element. It can be an Element, a string, or anything that provides a method toString(options?: OutputOptions).
In particular, the following classes are provided:
export class Comment {
constructor(public comment: string) {}
}export class CDATA {
constructor(public cdata: string) {}
}export class DocType {
constructor(public doctype: string) {}
}add(e: xml.Node)adds a node to anElement.remove(e: xml.Node)removes a node from anElement.setText(text: string)sets the firststringnode to the given text (or adds it if none).
Traversal
parentis the parentElementof thisElement(if any).childrenis an array of the child nodes in the order they were parsed from the xml file.firstElement()returns the first child that is anElement(if any).allElements()returns only the children that areElements.firstText()returns the first child that is anstring(if any).allText()returns only the children that arestrings. Usejointo combine them if necessary.
By name
elements returns an object whose property names are the names of the Element's child Elements. This allows for easy access to expected child Elements:
const xmlString = `<root><child>Text</child></root>`;
const rootElement = xml.parse(xmlString);
const child = rootElement.elements.child;
console.log(child.children[0]); // prints 'Text'Where there are multiple child nodes with the same name, accessing that property will return the first child of that name, but the rest can be recovered through the iterator defined on it (note: the first child is also returned by the iterator).
const xmlString = `<root><child>Text1</child><child>Text2</child><child>Text3</child></root>`;
const rootElement = xml.parse(xmlString);
const child = rootElement.elements.child;
console.log(child.children[0]); // prints 'Text1'
//iterate over all <child> nodes - prints 'Text1', 'Text2', 'Text3'
for (const i of child)
console.log(i.children[0]);Internals
SAX
The parse function uses a simple SAX parser which can be used externally:
export interface SaxOptions {
onerror?: (e: Error) => boolean | void;
ontext?: (t: string) => void;
ondoctype?: (doctype: string) => void;
onprocessing?: (name: string, body: string) => void;
onopentag?: (tagName: string, attributes: Attributes) => void;
onclosetag?: (tagName: string) => void;
oncomment?: (comment: string) => void;
oncdata?: (cdata: string) => void;
entities?: Entities;
}
export function sax(xml: string, options: SaxOptions);EntityCreator
The toString function uses the EntityCreator helper class which substitutes characters for the given entities. This can be used externally, and can be provided directly to the entities property of OutputOptions.
export class EntityCreator {
constructor(entities: Entities, from?: EntityCreator);
replace(text: string): string;
}License
This project is licensed under the MIT License.