steady-xml v0.1.0
steady-xml
English | 中文
A zero-dependence TypeScript library for the steady conversion and processing of XML data.
Origin
After I convert some XML data to JSON for processing, I expect to intact convert it back to XML data which including interlaced element nodes, CDATA nodes, DOCTYPE nodes, comments and so on.
I looked for some famous XML processing libraries (fast-xml-parser, node-xml2js), but most of them consistently chose a compressed conversion to pursue small space and high performance. Although I found a library (xml-js) that can retain as much information as possible, unfortunately it seems to unmaintained.
This is the origin of this library. The core of this library is to preserve XML information as much as possible during the conversion and processing so that the data can be restored intact. space and performance are not the primary concerns.
Features
This library using a class XmlNode
to describe XML nodes and relationships. It can construct XmlNode
tree from both XML data or JSON, or generate either XML data or JSON from XmlNode
.
The algorithm of XML data parsing is referred to fast-xml-parser to a certain extent, which is an excellent algorithm that provides a guarantee for the speed of parsing.
Currently can be resolved nodes:
- Element (includes attributes)
- Declaration (includes attributes)
- Comment
- DocumentType
- Text
- ProcessingInstruction
- CDATA
Install
yarn add steady-xml
Shorthand
XML to XmlNode
:
import { parseXmlString } from 'steady-xml'
const rootNode = parseXmlString('<element></element>')
XmlNode
to XML:
import { XmlNode, XmlNodeType } from 'steady-xml'
const rootNode = new XmlNode(XmlNodeType.Root)
rootNode.toXmlString()
rootNode.toXmlString('\t', '\n')
rootNode.toXmlString('', '')`${rootNode}`
JSON to XmlNode
:
import { buildFromJson } from 'steady-xml'
const rootNode = buildFromJson({ name: 'element' })
XmlNode
to JSON:
import { XmlNode, XmlNodeType } from 'steady-xml'
const rootNode = new XmlNode(XmlNodeType.Root)
rootNode.toJsObject()
JSON.stringify(rootNode)
Props
type TextValue = string | number | boolean | null
function parseXmlString(xmlString: string, props?: Partial<ParseProps>): XmlNode
interface ParseProps {
// ignore parse node attributes
// default: false
ignoreAttributes: boolean
// should parse node value
// default: true
parseNodeValue: boolean
// should trim string values
// default: true
trimValues: boolean
// parse node value method
// default: v => v
valueProcessor: (value: string, type: XmlNodeType, name: string) => TextValue
// parse attribute values method
// default: v => v
attributeProcessor: (value: string, name: string, type: XmlNodeType) => TextValue
}
function buildFromJson<T extends Record<string, any>>(json: T, props?: Partial<BuildProps>): XmlNode
interface BuildProps {
// name property key
// default: 'name'
nameKey: string
// type property key
// default: 'type'
typeKey: string
// value property key
// default: 'value'
valueKey: string
// attributes property key
// default: 'attributes'
attributesKey: string | false
// children property key
// default: 'children'
childrenKey: string
// self closing property key
// default: 'selfClosing'
selfClosingKey: string | false
// prefix property key
// default: 'prefix'
prefixKey: string | false
// should trim string values
// default: true
trimValues: boolean
// explicitly specify whether the json is a root node
// if be specified false, will judge according type
// if is not a root node, it will as element root node
// default: false
isRoot: boolean
// whether name includes prefix
// default: false
prefixInName: boolean
// parse node value method
// default: v => v
valueProcessor: (value: TextValue, type: XmlNodeType, name: string) => TextValue
// parse attribute values method
// default: v => v
attributeProcessor: (value: TextValue, name: string, type: XmlNodeType) => TextValue
}
enum XmlNodeType {
// is not a real XML node type, only use as the XML data entry
Root = 'Root',
// <?xml version="1.0"?>
Declaration = 'Declaration',
// <!-- some content -->
Comment = 'Comment',
// <!DOCTYPE Items [<!ENTITY number "123">]>
DocumentType = 'DocumentType',
// <element></element>
Element = 'Element',
// pure text node
Text = 'Text',
// <?pi target="target"?>
Instruction = 'Instruction',
// <![CDATA[<foo></bar>]]>
CDATA = 'CDATA'
}
interface XmlJsObject {
name?: string
prefix?: string
type: XmlNodeType
attributes?: Record<string, unknown>
value?: any
selfClosing?: true
children?: XmlJsObject[]
}
declare class XmlNode {
// node name
name: string
// node type
type: XmlNodeType
// parend node
parent: XmlNode | null
// chidl node list
children: XmlNode[] | null
// attribute map
attributes: Record<string, unknown>
// node value
value: any
// is self closing
selfClosing: boolean
// node prefix
prefix: string
constructor(name: string, type: XmlNodeType, parent?: XmlNode | null, value?: any)
// chain set name
setName(value: string): this
// chain set type
setType(value: XmlNodeType): this
// chain set parent node
setParent(value: XmlNode | null): this
// chain set children list
setChildren(value: XmlNode[] | null): this
// chain set attribute map
setAttributes(value: Record<string, unknown>): this
// chain set value
setValue(value: any): this
// chain set self closing
setSelfClosing(value: boolean): this
// chain set prefix
setPrefix(value: string): this
// chain add attribute
addAttribute(name: string, value: unknown): this
// chain remove attribute
removeAttribute(name: string): this
// chain add child node
addChild(childNode: XmlNode): void
// chain remove child node
removeChild(childNode: XmlNode): this
// generate json data
toJsObject(): XmlJsObject
// generate xml string data
toXmlString(indentChar?: string, newLine?: string, indentCount?: number): string
}
License
MIT License.
3 years ago