0.7.1 • Published 7 years ago

node-xml-zarf v0.7.1

Weekly downloads
3
License
MIT
Repository
github
Last release
7 years ago

Everybody writes XML parsing code, and this is mine.

It parses XML into Javascript data structures (in memory), according to a customizable set of conversion parameters. And it writes the data structures back out. The parser is built on SAX; the writer isn't built on anything but raw Node streams.

I don't plan to publish this to NPM because there must be a thousand packages that do this and mine isn't particularly clever. It does what I want and I might use it again someday.

Usage

Parsing

xmlparse.parse(source, struct, callback);

The source may be a pathname or an instance of stream.Readable. The call is always async; the callback has the form callback(doc, err). On success, err is null and doc is the parsed Javascript data.

The struct argument is a template of Javascript data, structured the way your XML will be. For example, the template might look like:

const struct = {
	root: {
		name: String,
		count: Number,
		obj: { 
			val: String
		},
		list: {
			_list: true,
			val: String
		}
	}
};

This would parse the XML file:

<root>
  <name>Title</name>
  <count>34</count>
  <obj><val>Foo</val></obj>
  <list>
	<val>Bar</val>
	<val>Baz</val>
  </list>
</root>

...into the Javascript form:

{
	root: {
		name: 'Title',
		count: 23,
		obj: { val: 'Foo' },
		list: [ 'Bar', 'Baz' ]
	}
}

The parsing is conservative; XML fields not mentioned in the structure are ignored.

Note that an object field in the template can be the symbol String, the symbol Number, or another object. The special field _list, if true, means that the child tags form a JS list rather than an object (their tag names are discarded).

In a list, if _wrapitem is true, the child objects are wrapped so that their tag names remain. That is, in the example above, you'd get

list: [ {val:'Bar'}, {val:'Baz'} ]

Normal (non-list) objects are wrapped by default. You can unwrap them by setting _bareobj true. Only do this for objects with at most one child! In the example above, if we add _bareobj: true to the obj subfield, we would get

{
	root: {
		name: 'Title',
		count: 23,
		obj: 'Foo',
		list: [ 'Bar', 'Baz' ]
	}
}

If you want custom classes or other post-processing, you can add an _result(o, attr) function to any object in the template. (The attr argument contains the XML attributes from the open tag.) This function can either modify o (and return undefined), or return any Javascript value.

Writing

xmlwrite.write(dest, struct, doc, cb)

The dest may be a pathname or an instance of stream.Writable. The call is always async; the callback has the form callback(err), where err is null on success.

The struct argument is a template of Javascript data, structured the way your XML will be.