Skip to content

Commit 3637c61

Browse files
committed
Add some auxiliary methods and doc string to XmlXPath
1 parent 9ed22d8 commit 3637c61

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

src/nodes.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ export abstract class XmlNode {
192192

193193
private compiledXPathEval(xpath: XmlXPath) {
194194
const context = xmlXPathNewContext(this._doc._docPtr);
195-
if (xpath._namespaces) {
196-
Object.entries(xpath._namespaces)
195+
if (xpath.namespaces) {
196+
Object.entries(xpath.namespaces)
197197
.forEach(([prefix, uri]) => {
198198
xmlXPathRegisterNs(context, prefix, uri);
199199
});

src/xpath.mts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,47 @@ export interface NamespaceMap {
1111
[prefix: string]: string;
1212
}
1313

14+
/**
15+
* XPath object.
16+
*
17+
* This object compiles the xpath at creation,
18+
* which could be reused many times, even for different documents.
19+
*
20+
* Note: This object requires to be {@link dispose}d explicitly.
21+
*/
1422
export class XmlXPath {
1523
_xpath: XmlXPathCompExprPtr;
1624

17-
_namespaces: NamespaceMap | undefined;
25+
private readonly _xpathSource;
26+
27+
private readonly _namespaces: NamespaceMap | undefined;
1828

1929
constructor(xpath: string, namespaces?: NamespaceMap) {
30+
this._xpathSource = xpath;
2031
this._xpath = xmlXPathCtxtCompile(0, xpath);
2132
this._namespaces = namespaces;
2233
}
2334

35+
/**
36+
* Dispose the XmlXPath.
37+
*
38+
* This needs to be called explicitly to avoid resource leak.
39+
*/
2440
dispose() {
2541
xmlXPathFreeCompExpr(this._xpath);
2642
}
43+
44+
/**
45+
* Namespaces and prefixes used.
46+
*/
47+
get namespaces(): NamespaceMap | undefined {
48+
return this._namespaces;
49+
}
50+
51+
/**
52+
* XPath string.
53+
*/
54+
toString(): string {
55+
return this._xpathSource;
56+
}
2757
}

test/xpath.spec.mts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,24 @@ describe('XPath', () => {
3232
const xpath = new XmlXPath('/book/m:title', { m: 'http://foo' });
3333
expect(doc.get(xpath)?.content).to.equal('Harry Potter');
3434
expect(doc.find(xpath).map((node) => node.content)).to.deep.equal(['Harry Potter']);
35+
xpath.dispose();
36+
});
37+
38+
it('should return undefined if namespace is not provided', () => {
39+
const xpath = new XmlXPath(('/book'));
40+
expect(xpath.namespaces).to.be.undefined;
41+
xpath.dispose();
42+
});
43+
44+
it('should return namespaces passed in', () => {
45+
const xpath = new XmlXPath('/book/m:title', { m: 'http://foo' });
46+
expect(xpath.namespaces).to.deep.equal({ m: 'http://foo' });
47+
xpath.dispose();
48+
});
49+
50+
it('should return xpath string by toString', () => {
51+
const xpath = new XmlXPath(('/book'));
52+
expect(xpath.toString()).to.equal('/book');
53+
xpath.dispose();
3554
});
3655
});

0 commit comments

Comments
 (0)