See below for a description of the entire format, but for a quick example, take the following XML:
With proper namespace aliasing configuration, you can get back the following plain object, regardless of what namespace aliases the original XML used. That's especially useful if the XML input is out of your control and you can't depend on it always having the same aliases.
npm install hugml
HugML.js follows semantic versioning, so feel free to depend on its major version with something like
>= 1.0.0 < 2 (a.k.a
var Hugml =Hugml // => Returns a plain object in the format described below.Hugml
The export from
require("hugml") has both static methods shown above and can be invoked as a constructor to configure namespaces and get back an instance of
Using the XML example above, you could set the
people namespace to be the default and
properties to be renamed as
var Hugml =var hugml ="urn:example:people": """urn:example:properties": "props"hugml
Tags in the
urn:example:people namespace will end up as unqualified properties (accessed
obj.people.person) and tags in the
urn:example:properties namespace will get the
props$ prefix. Values of tag attributes will still end up as string values of properties and the textual content of a tag will end up in a property called
To rename the default XML namespace to something else, use
"" as the namespace URI:
var hugml = "": "h"hugml
For serializing a plain object back to XML, just pass it in the same format as above to
Hugml.prototype.stringify. You don't need the namespace
xmlns attributes. They'll be added automatically based on the namespaces you've configured and the ones you've actually used.
var hugml = "urn:example:people": ""hugml
HugML.js has preliminary support for Exclusive XML Canonicalization. It may not be fully compliant yet and doesn't play well with parsed XML, but is enough to generate valid hashes of new XML generated by HugML.js for XML Digital Signatures.
To serialize canonicalized XML from a plain object, use the
var hugml = "urn:example:people": "people"hugml
This will then return a string following the exclusive canonicalization rules, such as minimally scoped namespaces, sorted attributes and lack of self-closing tags.
Occasionally you may want to canonicalize (and later hash and sign) only a subset of an XML document. Because canonicalization preserves XML tag indentation, you can't just extract that part of the object and pass it separately to the
canonicalize function. You'll need to pass the entire object and a path to the node you wish to be canonicalized:
var hugml = "urn:example:people": "people"var obj = "collection": "people$person": name: $: "John"hugml
This will return the canonicalized
<people:person> node with its closing tag properly indented:
hugml executable installed along with the library. You can use that to do quick tests.
If you've installed HugML.js globally, invoke
hugml. If you've installed it as a module in the current directory, you'll find
Give the executable an XML file to process. If you leave it out, it'll get the XML from stdin. It'll print the output to stdout.
hugml foo.xmlcurl http://example.com/foo.xml | hugml > foo.json
I used the executable to generate examples for this README by copying some XML to the clipboard and then used MacOS's
pbpaste to pass it on:
pbpaste | hugml
You can also set up namespace aliases for the CLI. Use the
hugml --namespace http://www.w3.org/2001/XMLSchema=schema <<end<?xml version="1.0" encoding="ISO-8859-1" ?><xs:schema xmlns:xs=""></xs:schema>end
It'll then print the following to stdout:
The general algorithm for converting between XML and JSON is as follows:
All XML is returned as an object with the XML pragma's attributes as properties of it:
Root tags will be added to that object as properties following the same rules as nested tags.
Tags will be converted to properties with the tag name as key and an object as value:
Tags in namespaces will retain their colon-separated name if it's an unknown alias:
If it's a renamed alias (see above for further details), its renamed alias will be concatenated with "$" and its local name:var hugml = "urn:example:people": "peeps"
Tag attributes will be converted to string properties of the above object value:
Tag textual content will be added as another property with the
Nested tags will be properties just like attributes, but following step 2, will have object values.
Note that because attributes and tags go on the same object, tags may collide with and shadow attributes. In practice that happens rarely and the convenience outweighs the risk. However, if it does affect you, you can work-around it by configuring a namespace:"": "h"
The serializing format you give to
Hugml.prototype.stringify matches the above and is applied in reverse.
HugML.js is released under a Lesser GNU Affero General Public License, which in summary means:
- You can use this program for no cost.
- You can use this program for both personal and commercial reasons.
- You do not have to share your own program's code which uses this program.
- You have to share modifications (e.g. bug-fixes) you've made to this program.
For more convoluted language, see the