Skip to content

Commit

Permalink
Lots of minor xpath futzing
Browse files Browse the repository at this point in the history
  • Loading branch information
hildjj committed May 8, 2023
1 parent fe18938 commit f170c10
Show file tree
Hide file tree
Showing 51 changed files with 714 additions and 331 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ console.log(doc.root.toString())
console.log(doc.get('//bar'))
```

Note that there is an implementation of XPath3 included. It is not
Note that there is an implementation of XPath3 included. It is not in any way
feature-complete yet, but it has a bunch of useful features already.

Full [documentation](https://hildjj.github.io/expat-wasm-dom/) is available.
Expand Down
7 changes: 6 additions & 1 deletion cli/bin/ewq.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/* eslint-disable no-console */
import {Command} from 'commander'
import {dom} from 'expat-wasm-dom'
import {parse} from '../lib/entity.js'
import {sharedOptions} from '../lib/shared.js'

Expand All @@ -21,7 +22,11 @@ async function main() {
const doc = await parse(arg, opts)
const res = doc.get(xpath)
for (const r of res) {
console.log(r.toString({colors: process.stdout.isTTY, depth: Infinity}))
if (r instanceof dom.Node) {
console.log(r.toString({colors: process.stdout.isTTY, depth: Infinity}))
} else {
console.log(r)
}
}
}
}
Expand Down
16 changes: 8 additions & 8 deletions docs/AttlistDecl.html

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions docs/Attribute.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/AttributeDecl.html

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions docs/CdataSection.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/Comment.html

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions docs/DoctypeDecl.html

Large diffs are not rendered by default.

25 changes: 14 additions & 11 deletions docs/Document.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DomParser.html

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/Element.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/ElementDecl.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/EntityDecl.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/Namespace.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Namespace_Namespace.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/Node.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/NotationDecl.html

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/ParentNode.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/ProcessingInstruction.html

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions docs/Text.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/XPath.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/XPathSyntaxError.html

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions docs/XmlDeclaration.html

Large diffs are not rendered by default.

33 changes: 18 additions & 15 deletions docs/dom.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/domParser.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-ConstructorParameters.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Exclude.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Extract.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-InstanceType.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-NonNullable.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Omit.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-OmitThisParameter.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Parameters.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Partial.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Pick.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Readonly.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Record.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-Required.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-ReturnType.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-ThisParameterType.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/external-ThisType.html

Large diffs are not rendered by default.

254 changes: 246 additions & 8 deletions docs/global.html

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions docs/index.html

Large diffs are not rendered by default.

62 changes: 53 additions & 9 deletions docs/xpath.js.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class Node {
* @param {string|XPath} pattern The pattern to match
* @param {Node} [context=this] The context node. Uses this node as context
* if none is provided.
* @returns {string|Node|null} The first match if one exists
* @returns {string|Node|number|null} The first match if one exists
*/
first(pattern, context) {
const res = this.get(pattern, context)
Expand Down Expand Up @@ -416,7 +416,7 @@ export class Document extends ParentNode {
* @param {string|XPath} pattern The pattern to match
* @param {Node} [context=this.root] The context node. Uses the root element
* as context if none is provided.
* @returns {string|Node|null} The first match if one exists
* @returns {string|number|Node|null} The first match if one exists
*/
first(pattern, context) {
return super.first(pattern, context || this.root || undefined)
Expand Down
49 changes: 42 additions & 7 deletions lib/xpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,24 @@ export class XPathSyntaxError extends Error {
}

/**
* @typedef {Array<string|dom.Node>} XPathResult
* @typedef {Array<string|number|dom.Node>} XPathResult
*/

/**
* @callback XPathFun
* @param {...XPathResult} params
* @return {XPathResult}
*/

/**
* @type {Record<string,XPathFun>}
*/
const XPathFunctions = {
count(context) {
return [context.length]
},
}

/**
* An XPath expression for querying an XML document
*/
Expand Down Expand Up @@ -177,12 +192,11 @@ export class XPath {
*/
// eslint-disable-next-line class-methods-use-this
_nameTestWildcard(num, context, star) {
/* c8 ignore next */
if (star !== '*') {
throw new Error(`Unimplemented wildcard: "${star}"`)
}
if (Array.isArray(context)) {
return context
return context.filter(e => e instanceof dom.Element)
} else if (context instanceof dom.Attribute) {
return [context]
} else if (context instanceof dom.Element) {
Expand Down Expand Up @@ -355,7 +369,7 @@ export class XPath {
*
* @param {dom.Node} context
* @param {Functor} expr
* @returns {string|dom.Node|undefined}
* @returns {string|number|dom.Node|undefined}
* @private
*/
_expr(context, expr) {
Expand Down Expand Up @@ -439,9 +453,7 @@ export class XPath {
*/
// eslint-disable-next-line class-methods-use-this
_comment(num, context) {
if (context instanceof dom.Comment) {
return [context]
} else if (Array.isArray(context)) {
if (Array.isArray(context)) {
return context.filter(n => n instanceof dom.Comment)
} else if (context instanceof dom.ParentNode) {
return context.children.filter(n => n instanceof dom.Comment)
Expand All @@ -465,6 +477,29 @@ export class XPath {
)
}

/**
* Execute functions.
*
* @param {number} num
* @param {dom.Node} context
* @param {string} fn
* @param {Functor[]} params
* @returns {XPathResult}
* @private
*/
_fn(num, context, fn, params) {
const fun = XPathFunctions[fn]
if (typeof fun !== 'function') {
throw new Error(`Unimplemented function: "${fn}"`)
}

const eparams = params.map(
v => this._eval([context], v)
)

return fun.apply(this, eparams)
}

/**
* Some operation that hasn't been implemented yet.
*
Expand Down
162 changes: 72 additions & 90 deletions lib/xpathPattern3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f170c10

Please sign in to comment.