/** * A parsed XML node */ export interface TNode { tagName: string; /** * Element attributes. Values can be: * - string: attribute with a value (e.g., `
` → `{id: "test"}`) * - null: attribute without a value (e.g., `` → `{disabled: null}`) * - empty string: attribute with empty value (e.g., `` → `{value: ""}`) */ attributes: Record; children: (TNode | string)[]; /** True when this node was parsed from an explicit self-closing tag like `` */ selfClosed?: boolean; } /** * Options for parsing XML */ export interface ParseOptions { /** Starting position in the string */ pos?: number; /** * Array of tag names that are self-closing (void elements) and don't need closing tags. * Default: ['img', 'br', 'input', 'meta', 'link', 'hr'] * @deprecated Use selfClosingTags instead */ noChildNodes?: string[]; /** * Array of tag names that are self-closing (void elements) and don't need closing tags. * Default: ['img', 'br', 'input', 'meta', 'link', 'hr'] */ selfClosingTags?: string[]; /** If true, the returned object will have a pos property indicating where parsing stopped */ setPos?: boolean; /** Keep XML comments in the output */ keepComments?: boolean; /** Keep whitespace text nodes */ keepWhitespace?: boolean; /** * @deprecated Use keepWhitespace instead */ keepWhitespaces?: boolean; /** Decode XML entities in text and attribute values (e.g. `&` -> `&`) */ decodeEntities?: boolean; /** Skip XML declaration/processing instructions such as */ skipXmlDeclaration?: boolean; /** Automatically simplify the output */ simplify?: boolean; /** Parse a single node instead of a list of nodes */ parseNode?: boolean; /** Attribute name to search for (used with attrValue) */ attrName?: string; /** Attribute value to search for (regex pattern) */ attrValue?: string; /** Filter function to apply to nodes */ filter?: (node: TNode, index: number, depth: number, path: string) => boolean; } /** * Options for stringifying XML */ export interface StringifyOptions { /** Encode XML entities in text and attribute values (e.g. `&` -> `&`) */ encodeEntities?: boolean; /** Preserve whitespace text nodes during serialization */ keepWhitespace?: boolean; /** * @deprecated Use keepWhitespace instead */ keepWhitespaces?: boolean; /** Serialize empty elements as self-closing tags (e.g. ``). Default: true. Nodes with `selfClosed: true` are always serialized as self-closing. */ selfCloseEmpty?: boolean; } /** * Parse XML/HTML into a DOM Object with minimal validation and fault tolerance * @param xml - The XML string to parse * @param options - Parsing options * @returns Array of parsed nodes and text content */ export function parse(xml: string, options?: ParseOptions): (TNode | string)[]; /** * Transform the DOM object to a simpler format like PHP's SimpleXML * Note: The order of elements is not preserved, and the original XML cannot be reproduced * @param children - Array of nodes to simplify, or raw XML string * @returns Simplified object structure */ export function simplify(children: TNode[] | string): Record | string; /** * Similar to simplify, but preserves more information * @param children - Array of nodes to simplify * @param parentAttributes - Parent node attributes * @returns Simplified object structure with less data loss */ export function simplifyLostLess( children: TNode[], parentAttributes?: Record ): Record; /** * Filter nodes like Array.filter - returns nodes where the filter function returns true * @param children - Array of nodes to filter * @param f - Filter function * @param depth - Current depth in the tree (internal use) * @param path - Current path in the tree (internal use) * @returns Filtered array of nodes */ export function filter( children: (TNode | string)[], f: (node: TNode, index: number, depth: number, path: string) => boolean, depth?: number, path?: string ): TNode[]; /** * Stringify a parsed object back to XML * Useful for removing whitespace or recreating XML with modified data * @param node - The node(s) to stringify * @param options - Stringify options * @returns XML string */ export function stringify(node: TNode | (TNode | string)[], options?: StringifyOptions): string; /** * Read the text content of a node, useful for mixed content * Example: "this text has some big text and a link" * @param tDom - The node(s) to extract text from * @returns Concatenated text content */ export function toContentString(tDom: TNode | (TNode | string)[]): string; /** * Find an element by ID attribute * @param xml - XML string to search * @param id - ID value to find * @param simplified - Whether to return simplified output * @returns Found node(s) */ export function getElementById(xml: string, id: string, simplified?: boolean): TNode | Record; /** * Find elements by class name * @param xml - XML string to search * @param classname - Class name to find * @param simplified - Whether to return simplified output * @returns Found nodes */ export function getElementsByClassName(xml: string, classname: string, simplified?: boolean): TNode[] | Record; /** * Type guard to check if a node is a text node (string) * @param node - The node to check * @returns True if the node is a string (text node) * @example * const parsed = parse('
Hello World
'); * parsed[0].children.forEach(child => { * if (isTextNode(child)) { * console.log('Text:', child); * } else { * console.log('Element:', child.tagName); * } * }); */ export function isTextNode(node: TNode | string): node is string; /** * Type guard to check if a node is an element node (TNode) * @param node - The node to check * @returns True if the node is a TNode (element node) * @example * const parsed = parse('
Hello World
'); * parsed[0].children.forEach(child => { * if (isElementNode(child)) { * console.log('Element:', child.tagName); * } else { * console.log('Text:', child); * } * }); */ export function isElementNode(node: TNode | string): node is TNode;