Skip to content

Commit

Permalink
feat: add the resolvePrefix option
Browse files Browse the repository at this point in the history
This is yet another option for facilitating parsing XML fragments. This option
is a callback that the parser will call if it is not able to resolve a namespace
prefix.
  • Loading branch information
lddubeau committed Aug 20, 2018
1 parent 41cc3ed commit 90301fb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ event.

The XML specification does not define any method by which to parse XML
fragments. However, there are usage scenarios in which it is desirable to parse
fragments. In order to allow this, saxes provides two initialization options.
fragments. In order to allow this, saxes provides three initialization options.

If you pass the option `fragment: true` to the parser constructor, the parser
will expect an XML fragment. It essentially starts with a parsing state
Expand All @@ -187,8 +187,17 @@ right after initialization. In other words, it expects content which is
acceptable inside an element. This also turns off well-formedness checks that
are inappropriate when parsing a fragment.

The other option is `additionalNamespaces`, which allows you to define
additional prefix-to-URI bindings known before parsing starts.
The option `additionalNamespaces` allows you to define additional prefix-to-URI
bindings known before parsing starts. You would use this over `resolvePrefix` if
you have at the ready a series of namespaces bindings to use.

The option `resolvePrefix` allows you to pass a function which saxes will use if
it is unable to resolve a namespace prefix by itself. You would use this over
`additionalNamespaces` in a context where getting a complete list of defined
namespaces is onerous.

Note that you can use `additionalNamespaces` and `resolvePrefix` together if you
want. `additionalNamespaces` applies before `resolvePrefix`.

## FAQ

Expand Down
19 changes: 18 additions & 1 deletion lib/saxes.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ ${XMLNS_NAMESPACE}.`);
* specified by the XML declaration.
*/

/**
* @callback ResolvePrefix
*
* @param {string} prefix The prefix to check.
*
* @returns {string|undefined} The URI corresponding to the prefix, if any.
*/

/**
* @typedef SaxesOptions
*
Expand All @@ -235,6 +243,9 @@ ${XMLNS_NAMESPACE}.`);
* pairs define namespaces known before parsing the XML file. It is not legal
* to pass bindings for the namespaces ``"xml"`` or ``"xmlns"``.
*
* @property {ResolvePrefix} [resolvePrefix] A function that will be used if the
* parser cannot resolve a namespace prefix on its own.
*
* @property {boolean} [position] Whether to track positions. Unset means
* ``true``.
*
Expand Down Expand Up @@ -1569,7 +1580,13 @@ class SaxesParser {
}
}

return this.ns[prefix];
uri = this.ns[prefix];
if (uri) {
return uri;
}

const { resolvePrefix } = this.opt;
return resolvePrefix ? resolvePrefix(prefix) : undefined;
}

/**
Expand Down
42 changes: 42 additions & 0 deletions test/fragments.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,46 @@ describe("fragments", () => {
},
},
});

test({
name: "resolvePrefix",
xml: "Something <foo:blah>1</foo:blah> something",
expect: [
["text", "Something "],
["opentagstart", {
name: "foo:blah",
attributes: {},
ns: {},
}],
["opentag", {
name: "foo:blah",
local: "blah",
prefix: "foo",
uri: "foo-uri",
attributes: {},
ns: {},
isSelfClosing: false,
}],
["text", "1"],
["closetag", {
name: "foo:blah",
local: "blah",
prefix: "foo",
uri: "foo-uri",
attributes: {},
ns: {},
isSelfClosing: false,
}],
["text", " something"],
],
opt: {
xmlns: true,
fragment: true,
resolvePrefix(prefix) {
return {
foo: "foo-uri",
}[prefix];
},
},
});
});

0 comments on commit 90301fb

Please sign in to comment.