forked from enviPath/enviPy
Current Dev State
This commit is contained in:
130
static/js/ketcher2/node_modules/xpath/README.md
generated
vendored
Normal file
130
static/js/ketcher2/node_modules/xpath/README.md
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
## xpath
|
||||
DOM 3 XPath 1.0 implemention and helper for JavaScript, with node.js support.
|
||||
|
||||
Originally written by Cameron McCormack ([blog](http://mcc.id.au/xpathjs)).
|
||||
|
||||
Additional contributions from
|
||||
Yaron Naveh ([blog](http://webservices20.blogspot.com/))
|
||||
goto100
|
||||
Thomas Weinert
|
||||
Jimmy Rishe
|
||||
and [others](https://github.com/goto100/xpath/graphs/contributors)
|
||||
|
||||
## Install
|
||||
Install with [npm](http://github.com/isaacs/npm):
|
||||
|
||||
npm install xpath
|
||||
|
||||
xpath is xml engine agnostic but I recommend to use [xmldom](https://github.com/jindw/xmldom):
|
||||
|
||||
npm install xmldom
|
||||
|
||||
## API Documentation
|
||||
|
||||
Can be found [here](https://github.com/goto100/xpath/blob/master/docs/xpath%20methods.md). See below for example usage.
|
||||
|
||||
## Your first xpath:
|
||||
`````javascript
|
||||
var xpath = require('xpath')
|
||||
, dom = require('xmldom').DOMParser
|
||||
|
||||
var xml = "<book><title>Harry Potter</title></book>"
|
||||
var doc = new dom().parseFromString(xml)
|
||||
var nodes = xpath.select("//title", doc)
|
||||
|
||||
console.log(nodes[0].localName + ": " + nodes[0].firstChild.data)
|
||||
console.log("Node: " + nodes[0].toString())
|
||||
`````
|
||||
➡
|
||||
|
||||
title: Harry Potter
|
||||
Node: <title>Harry Potter</title>
|
||||
|
||||
### Alternatively
|
||||
|
||||
Using the same interface you have on modern browsers ([MDN])
|
||||
|
||||
`````javascript
|
||||
var node = null;
|
||||
var xml = "<book author='J. K. Rowling'><title>Harry Potter</title></book>"
|
||||
var doc = new dom().parseFromString(xml)
|
||||
var result = xpath.evaluate(
|
||||
"/book/title", // xpathExpression
|
||||
doc, // contextNode
|
||||
null, // namespaceResolver
|
||||
xpath.XPathResult.ANY_TYPE, // resultType
|
||||
null // result
|
||||
)
|
||||
|
||||
node = result.iterateNext();
|
||||
while (node) {
|
||||
console.log(node.localName + ": " + node.firstChild.data);
|
||||
console.log("Node: " + node.toString());
|
||||
|
||||
node = result.iterateNext();
|
||||
}
|
||||
`````
|
||||
➡
|
||||
|
||||
title: Harry Potter
|
||||
Node: <title>Harry Potter</title>
|
||||
|
||||
## Evaluate string values directly:
|
||||
`````javascript
|
||||
var xml = "<book><title>Harry Potter</title></book>";
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var title = xpath.select("string(//title)", doc);
|
||||
|
||||
console.log(title);
|
||||
`````
|
||||
➡
|
||||
|
||||
Harry Potter
|
||||
|
||||
## Namespaces
|
||||
`````javascript
|
||||
var xml = "<book><title xmlns='myns'>Harry Potter</title></book>"
|
||||
var doc = new dom().parseFromString(xml)
|
||||
var node = xpath.select("//*[local-name(.)='title' and namespace-uri(.)='myns']", doc)[0]
|
||||
|
||||
console.log(node.namespaceURI)
|
||||
`````
|
||||
➡
|
||||
|
||||
myns
|
||||
|
||||
## Namespaces with easy mappings
|
||||
`````javascript
|
||||
var xml = "<book xmlns:bookml='http://example.com/book'><bookml:title>Harry Potter</bookml:title></book>"
|
||||
var select = xpath.useNamespaces({"bookml": "http://example.com/book"});
|
||||
|
||||
console.log(select('//bookml:title/text()', doc)[0].nodeValue);
|
||||
`````
|
||||
➡
|
||||
|
||||
Harry Potter
|
||||
|
||||
## Default namespace with mapping
|
||||
`````javascript
|
||||
var xml = "<book xmlns='http://example.com/book'><title>Harry Potter</title></book>"
|
||||
var select = xpath.useNamespaces({"bookml": "http://example.com/book"});
|
||||
|
||||
console.log(select('//bookml:title/text()', doc)[0].nodeValue);
|
||||
`````
|
||||
➡
|
||||
|
||||
Harry Potter
|
||||
|
||||
## Attributes
|
||||
`````javascript
|
||||
var xml = "<book author='J. K. Rowling'><title>Harry Potter</title></book>"
|
||||
var doc = new dom().parseFromString(xml)
|
||||
var author = xpath.select1("/book/@author", doc).value
|
||||
|
||||
console.log(author)
|
||||
`````
|
||||
➡
|
||||
|
||||
J. K. Rowling
|
||||
|
||||
[MDN]: https://developer.mozilla.org/en/docs/Web/API/Document/evaluate
|
||||
68
static/js/ketcher2/node_modules/xpath/docs/XPathEvaluator.md
generated
vendored
Normal file
68
static/js/ketcher2/node_modules/xpath/docs/XPathEvaluator.md
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
# `XPathEvaluator`
|
||||
|
||||
The `xpath.parse()` method returns an `XPathEvaluator`, which contains the following methods.
|
||||
|
||||
Each of these methods takes an optional `options` object, which can contain any of the following properties:
|
||||
|
||||
`namespaces` - a namespace resolver. See the [documentation page](namespace resolvers.md) for details.
|
||||
|
||||
`variables` - a variable resolver. See the [documentation page](variable resolvers.md) for details.
|
||||
|
||||
`functions` - a function resolver. See the [documentation page](function resolvers.md) for details.
|
||||
|
||||
`node` - the context node for evaluating the expression
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('/characters/character[@greeting = $greeting]');
|
||||
var character = evaluator.select1({
|
||||
node: myCharacterDoc,
|
||||
variables: {
|
||||
greeting: 'Hello, I'm Harry, Harry Potter.`
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## `XPathEvaluator` methods
|
||||
|
||||
`evaluate([options])`
|
||||
|
||||
Evaluates the XPath expression and returns the result. The resulting type is determined based on the type of the expression, using the same criteria as [`xpath.select`](xpath methods.md).
|
||||
|
||||
`evaluateNumber([options])`
|
||||
|
||||
Evaluates the XPath expression and returns the result as a number.
|
||||
|
||||
`evaluateString([options])`
|
||||
|
||||
Evaluates the XPath expression and returns the result as a string.
|
||||
|
||||
`evaluateBoolean([options])`
|
||||
|
||||
Evaluates the XPath expression and returns the result as a boolean value.
|
||||
|
||||
`evaluateNodeSet([options])`
|
||||
|
||||
Evaluates the XPath expression and returns the result as an XNodeSet. See the [documentation page](#) for details on this interface.
|
||||
|
||||
This is only valid for expressions that evaluate to a node set.
|
||||
|
||||
`select([options])`
|
||||
|
||||
Evaluates the XPath expression and returns an array of the resulting nodes, in document order.
|
||||
|
||||
This is only valid for expressions that evaluate to a node set.
|
||||
|
||||
`select([options])`
|
||||
|
||||
Evaluates the XPath expression and returns an array of the resulting nodes, in document order.
|
||||
|
||||
This is only valid for expressions that evaluate to a node set.
|
||||
|
||||
`select1([options])`
|
||||
|
||||
Evaluates the XPath expression and the first node in the resulting node set, in document order. Returns `undefined`
|
||||
|
||||
This is only valid for expressions that evaluate to a node set.
|
||||
|
||||
47
static/js/ketcher2/node_modules/xpath/docs/XPathResult.md
generated
vendored
Normal file
47
static/js/ketcher2/node_modules/xpath/docs/XPathResult.md
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
# XPathResult interface
|
||||
|
||||
Represents the result of an XPath expression. This interface is used for the parameters passed into custom functions
|
||||
used in [function resolvers](function resolvers.md) and can represent a number, a string, a boolean value, or a node set.
|
||||
|
||||
## Methods
|
||||
|
||||
```js
|
||||
booleanValue() -> boolean
|
||||
```
|
||||
|
||||
Returns the boolean value of the result in accordance with the XPath 1.0 spec.
|
||||
|
||||
```js
|
||||
numberValue() -> number
|
||||
```
|
||||
|
||||
Returns the numeric value of the result in accordance with the XPath 1.0 spec.
|
||||
|
||||
```js
|
||||
stringValue() -> string
|
||||
```
|
||||
|
||||
Returns the string value of the result in accordance with the XPath 1.0 spec.
|
||||
|
||||
## Methods and properties that are only present on `XPathResult`s representing node sets
|
||||
|
||||
```js
|
||||
toArray() -> Array of nodes
|
||||
```
|
||||
|
||||
Returns an array of the nodes in the node set, in document order.
|
||||
|
||||
```js
|
||||
first() -> Node
|
||||
```
|
||||
|
||||
Returns the first node in the node set, in document order.
|
||||
|
||||
```js
|
||||
size -> number
|
||||
```
|
||||
|
||||
Returns the number of nodes in this node set
|
||||
|
||||
|
||||
|
||||
88
static/js/ketcher2/node_modules/xpath/docs/function resolvers.md
generated
vendored
Normal file
88
static/js/ketcher2/node_modules/xpath/docs/function resolvers.md
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
# Function Resolvers
|
||||
|
||||
The methods on the [XPathEvaluator](XPathEvaluator.md) type can optionally take a function resolver to resolve
|
||||
function references in the XPath expression being evaluated.
|
||||
|
||||
There are three ways to specify a function resolver and you can use any one of them depending on which is
|
||||
most suited to your particular situation.
|
||||
|
||||
Note that if your functions are in a namespace (e.g. `fn:myFunction()`), you must use the second or third
|
||||
type as the plain object implementation does not support namespaces.
|
||||
|
||||
## Function implementations
|
||||
|
||||
Custom XPath functions are implemented as JavaScript functions taking one or more arguments.
|
||||
|
||||
The first argument passed in is a context object containing a number of properties relating to the execution context,
|
||||
the most important being `contextNode`, the context in which the function is being evaluated.
|
||||
|
||||
The remaining arguments are the arguments passed into the XPath function, as instances of the `XPathResult` interface.
|
||||
Please see [the documentation on that interface](XPathResult.md) for details.
|
||||
|
||||
As the return value, you can return a string, number, boolean, single node, or array of nodes.
|
||||
|
||||
## Function Resolver Type 1: Plain object
|
||||
|
||||
A plain object with function names as the keys and function implementations as the values.
|
||||
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('squareRoot(10)');
|
||||
var aboutPi = evaluator.evaluateNumber({
|
||||
functions: {
|
||||
'squareRoot': function (c, value) {
|
||||
return Math.sqrt(value.numberValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Function Resolver Type 2: Function
|
||||
|
||||
A function that takes a function name as its first parameter and an optional namespace URI as its second parameter
|
||||
and returns a function based on the name and namespace.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('math:squareRoot(10)');
|
||||
var aboutPi = evaluator.evaluateNumber({
|
||||
functions: function (name, namespace) {
|
||||
if (name === 'squareRoot' && namespace === 'http://sample.org/math/') {
|
||||
return function (c, value) {
|
||||
return Math.sqrt(value.numberValue());
|
||||
};
|
||||
}
|
||||
},
|
||||
namespaces: {
|
||||
math: 'http://sample.org/math/'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Function Resolver Type 3: Object with `getFunction` method
|
||||
|
||||
An object with a method named `getFunction` that works in the same way as the function-based function resolver
|
||||
described above.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('math:squareRoot(10)');
|
||||
var aboutPi = evaluator.evaluateNumber({
|
||||
functions: {
|
||||
getFunction: function (name, namespace) {
|
||||
if (name === 'squareRoot' && namespace === 'http://sample.org/math/') {
|
||||
return function (c, value) {
|
||||
return Math.sqrt(value.numberValue());
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
namespaces: {
|
||||
math: 'http://sample.org/math/'
|
||||
}
|
||||
});
|
||||
```
|
||||
69
static/js/ketcher2/node_modules/xpath/docs/namespace resolvers.md
generated
vendored
Normal file
69
static/js/ketcher2/node_modules/xpath/docs/namespace resolvers.md
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
# Namespace Resolvers
|
||||
|
||||
The methods on the [XPathEvaluator](XPathEvaluator.md) type can optionally take a namespace resolver to resolve
|
||||
namespace references in the XPath expression being evaluated.
|
||||
|
||||
There are three ways to specify a namespace resolver and you can use any one of them depending on which is
|
||||
most suited to your particular situation.
|
||||
|
||||
## Namespace Resolver Type 1: Plain object
|
||||
|
||||
A plain object with namespace prefixes as the keys and namespace URIs as the values:
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('/bk:book/hp:characters');
|
||||
var characters = evaluator.select({
|
||||
node: myBookNode,
|
||||
namespaces: {
|
||||
'bk': 'http://sample.org/books/',
|
||||
'hp': 'http://sample.org/harrypotter/'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Namespace Resolver Type 2: Function
|
||||
|
||||
A function that takes a namespace prefix as a parameter and returns the corresponding namespace URI.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('/bk:book/hp:characters');
|
||||
var characters = evaluator.select({
|
||||
node: myBookNode,
|
||||
namespaces: function (prefix) {
|
||||
if (prefix === 'bk') {
|
||||
return 'http://sample.org/books/';
|
||||
}
|
||||
if (prefix === 'hp') {
|
||||
return 'http://sample.org/books/';
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Namespace Resolver Type 3: Object with `getNamespace` method
|
||||
|
||||
An object with a method named `getNamespace` that works in the same way as the function-based namespace resolver
|
||||
described above.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('/bk:book/hp:characters');
|
||||
var characters = evaluator.select({
|
||||
node: myBookNode,
|
||||
namespaces: {
|
||||
getNamespace: function (prefix) {
|
||||
if (prefix === 'bk') {
|
||||
return 'http://sample.org/books/';
|
||||
}
|
||||
if (prefix === 'hp') {
|
||||
return 'http://sample.org/books/';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
21
static/js/ketcher2/node_modules/xpath/docs/parsed expressions.md
generated
vendored
Normal file
21
static/js/ketcher2/node_modules/xpath/docs/parsed expressions.md
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Using Parsed Expressions
|
||||
|
||||
The `xpath.parse()` method allows pre-parsing an XPath expression and creating an XPath executor to evaluate the XPath as many times as needed.
|
||||
|
||||
This can provide a performance benefit if you plan to evaluate the same XPath multiple times because the expression only needs to be parsed once.
|
||||
|
||||
This also provides access to additional features such as the use of variables and custom XPath functinos, which are not available using the evaluation methods on the `xpath` object.
|
||||
|
||||
#### xpath.parse(expression)
|
||||
|
||||
Parses the specified XPath expression and returns an `XPathEvaluator`. See the [documentation page](XPathEvaluator.md) for API details.
|
||||
|
||||
`expression` should be a string.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var evaluator = xpath.parse('/book/characters');
|
||||
```
|
||||
|
||||
|
||||
89
static/js/ketcher2/node_modules/xpath/docs/variable resolvers.md
generated
vendored
Normal file
89
static/js/ketcher2/node_modules/xpath/docs/variable resolvers.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
# Variable Resolvers
|
||||
|
||||
The methods on the [XPathEvaluator](#) type can optionally take a variable resolver to resolve
|
||||
variable references in the XPath expression being evaluated.
|
||||
|
||||
There are three ways to specify a variable resolver and you can use any one of them depending on which is
|
||||
most suited to your particular situation.
|
||||
|
||||
Note that if your variables are in a namespace (e.g. `$myVars:var`), you must use the second or third
|
||||
type as the plain object implementation does not support namespaces.
|
||||
|
||||
## Variable values
|
||||
|
||||
You can use any of five types of values to specify the values of variables:
|
||||
|
||||
- string
|
||||
- number
|
||||
- boolean
|
||||
- single node (will be treated as a node set)
|
||||
- array of nodes or array-like collection of nodes (will be treated as a node set)
|
||||
|
||||
## Variable Resolver Type 1: Plain object
|
||||
|
||||
A plain object with variable names as the keys and variable values as the values.
|
||||
|
||||
Example usage:
|
||||
|
||||
````
|
||||
var evaluator = xpath.parse('concat($character1, ", ", $character2, ", and ", $character3)');
|
||||
var mainCharacters = evaluator.evaluateString({
|
||||
variables: {
|
||||
character1: 'Harry',
|
||||
character2: 'Ron',
|
||||
character3: 'Hermione'
|
||||
}
|
||||
});
|
||||
````
|
||||
|
||||
## Variable Resolver Type 2: Function
|
||||
|
||||
A function that takes a variable name as its first parameter and an optional namespace URI as its second parameter
|
||||
and returns a value based on the name and namespace.
|
||||
|
||||
Example usage:
|
||||
|
||||
````
|
||||
var evaluator = xpath.parse('concat($hp:character1, ", ", $hp:character2, ", and ", $hp:character3)');
|
||||
var mainCharacters = evaluator.evaluateString({
|
||||
variables: function (name, namespace) {
|
||||
if (namespace === 'http://sample.org/harrypotter/') {
|
||||
switch (name) {
|
||||
case 'character1': return 'Harry';
|
||||
case 'character2': return 'Ron';
|
||||
case 'character3': return 'Hermione';
|
||||
}
|
||||
}
|
||||
},
|
||||
namespaces: {
|
||||
hp: 'http://sample.org/harrypotter/'
|
||||
}
|
||||
});
|
||||
````
|
||||
|
||||
## Function Resolver Type 3: Object with `getFunction` method
|
||||
|
||||
An object with a method named `getVariable` that works in the same way as the function-based variable resolver
|
||||
described above.
|
||||
|
||||
Example usage:
|
||||
|
||||
````
|
||||
var evaluator = xpath.parse('concat($hp:character1, ", ", $hp:character2, ", and ", $hp:character3)');
|
||||
var mainCharacters = evaluator.evaluateString({
|
||||
variables: {
|
||||
getVariable: function (name, namespace) {
|
||||
if (namespace === 'http://sample.org/harrypotter/') {
|
||||
switch (name) {
|
||||
case 'character1': return 'Harry';
|
||||
case 'character2': return 'Ron';
|
||||
case 'character3': return 'Hermione';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
namespaces: {
|
||||
hp: 'http://sample.org/harrypotter/'
|
||||
}
|
||||
});
|
||||
````
|
||||
39
static/js/ketcher2/node_modules/xpath/docs/xpath methods.md
generated
vendored
Normal file
39
static/js/ketcher2/node_modules/xpath/docs/xpath methods.md
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#xpath methods
|
||||
|
||||
This page details the methods exposed on the `xpath` object.
|
||||
|
||||
### `xpath.select(expression[, node[, single]])`
|
||||
|
||||
Evaluates an XPath expression and returns the result. The return value is determined based on the result type of the expression (which can always be predicted ahead of time):
|
||||
|
||||
- A boolean value if the expression evaluates to a boolean value.
|
||||
- A number if the expression evaluates to a numeric value.
|
||||
- A string if the expression evaluates to a string.
|
||||
- If the expression evaluates to a nodeset:
|
||||
- An array of nodes if `single` is unspecified or falsy
|
||||
- A single node (the first node in document order) or `undefined` if `single` is truthy
|
||||
|
||||
`node` is optional and if specified, is used as the context node for evaluating the expression. (It is necessary if the expression includes any node tests.)
|
||||
|
||||
`single` is optional and is ignored if the expression evaluates to anything other than a nodeset.
|
||||
|
||||
### `xpath.useNamespaces(mappings)`
|
||||
|
||||
Produces a function with the signature `func(expression, node)` that evaluates the provided xpath expression with the XML namespace definitions provided in `mapppings`.
|
||||
|
||||
`mappings` should be an object with namespace prefixes as its property names and namespace URIs as its property values.
|
||||
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
var expr = xpath.useNamespaces({ hp: 'http://www.example.com/harryPotter', bk: 'http://www.example.com/books' });
|
||||
var result = expr('/bk:books/bk:book[@name = "Harry Potter and the Half-Blood Prince"]/hp:characters', myBooks);
|
||||
```
|
||||
|
||||
### `xpath.select1(expression[, node])`
|
||||
|
||||
Alias for [`xpath.select(expression, node, true)`](#xpathselectexpression-node-single). Selects a single node or value.
|
||||
|
||||
### `xpath.parse(expression)`
|
||||
|
||||
Creates a parsed expression. See the [documentation page](parsed expressions.md) for details.
|
||||
67
static/js/ketcher2/node_modules/xpath/package.json
generated
vendored
Normal file
67
static/js/ketcher2/node_modules/xpath/package.json
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
{
|
||||
"_from": "xpath@0.0.24",
|
||||
"_id": "xpath@0.0.24",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs=",
|
||||
"_location": "/xpath",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "xpath@0.0.24",
|
||||
"name": "xpath",
|
||||
"escapedName": "xpath",
|
||||
"rawSpec": "0.0.24",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "0.0.24"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#DEV:/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz",
|
||||
"_shasum": "1ade162e1cc523c8d39fc7d06afc16ea216f29fb",
|
||||
"_spec": "xpath@0.0.24",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher",
|
||||
"author": {
|
||||
"name": "Cameron McCormac"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/goto100/xpath/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "goto100"
|
||||
},
|
||||
{
|
||||
"name": "James Rishe"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "DOM 3 XPath implemention and helper for node.js.",
|
||||
"devDependencies": {
|
||||
"nodeunit": ">=0.6.4",
|
||||
"xmldom": "^0.1.19"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
},
|
||||
"homepage": "https://github.com/goto100/xpath#readme",
|
||||
"keywords": [
|
||||
"xpath",
|
||||
"xml"
|
||||
],
|
||||
"license": "CC-BY-SA-2.0",
|
||||
"main": "./xpath.js",
|
||||
"name": "xpath",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/goto100/xpath.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "nodeunit test.js"
|
||||
},
|
||||
"typings": "./xpath.d.ts",
|
||||
"version": "0.0.24"
|
||||
}
|
||||
855
static/js/ketcher2/node_modules/xpath/test.js
generated
vendored
Normal file
855
static/js/ketcher2/node_modules/xpath/test.js
generated
vendored
Normal file
@ -0,0 +1,855 @@
|
||||
var xpath = require('./xpath.js')
|
||||
, dom = require('xmldom').DOMParser
|
||||
, assert = require('assert');
|
||||
|
||||
module.exports = {
|
||||
'api': function(test) {
|
||||
assert.ok(xpath.evaluate, 'evaluate api ok.');
|
||||
assert.ok(xpath.select, 'select api ok.');
|
||||
assert.ok(xpath.parse, 'parse api ok.');
|
||||
test.done();
|
||||
},
|
||||
|
||||
'evaluate': function(test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var nodes = xpath.evaluate('//title', doc, null, xpath.XPathResult.ANY_TYPE, null).nodes;
|
||||
assert.equal('title', nodes[0].localName);
|
||||
assert.equal('Harry Potter', nodes[0].firstChild.data);
|
||||
assert.equal('<title>Harry Potter</title>', nodes[0].toString());
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select': function(test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var nodes = xpath.select('//title', doc);
|
||||
assert.equal('title', nodes[0].localName);
|
||||
assert.equal('Harry Potter', nodes[0].firstChild.data);
|
||||
assert.equal('<title>Harry Potter</title>', nodes[0].toString());
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select single node': function(test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
assert.equal('title', xpath.select('//title[1]', doc)[0].localName);
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select text node': function (test) {
|
||||
var xml = '<book><title>Harry</title><title>Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
assert.deepEqual('book', xpath.select('local-name(/book)', doc));
|
||||
assert.deepEqual('Harry,Potter', xpath.select('//title/text()', doc).toString());
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select number node': function(test) {
|
||||
var xml = '<book><title>Harry</title><title>Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
assert.deepEqual(2, xpath.select('count(//title)', doc));
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select xpath with namespaces': function (test) {
|
||||
var xml = '<book><title xmlns="myns">Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var nodes = xpath.select('//*[local-name(.)="title" and namespace-uri(.)="myns"]', doc);
|
||||
assert.equal('title', nodes[0].localName);
|
||||
assert.equal('myns', nodes[0].namespaceURI) ;
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select xpath with namespaces, using a resolver': function (test) {
|
||||
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var resolver = {
|
||||
mappings: {
|
||||
'testns': 'http://example.com/test'
|
||||
},
|
||||
lookupNamespaceURI: function(prefix) {
|
||||
return this.mappings[prefix];
|
||||
}
|
||||
}
|
||||
|
||||
var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
|
||||
assert.equal('Harry Potter', xpath.selectWithResolver('//testns:title/text()', doc, resolver)[0].nodeValue);
|
||||
assert.equal('JKR', xpath.selectWithResolver('//testns:field[@testns:type="author"]/text()', doc, resolver)[0].nodeValue);
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select xpath with default namespace, using a resolver': function (test) {
|
||||
var xml = '<book xmlns="http://example.com/test"><title>Harry Potter</title><field type="author">JKR</field></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var resolver = {
|
||||
mappings: {
|
||||
'testns': 'http://example.com/test'
|
||||
},
|
||||
lookupNamespaceURI: function(prefix) {
|
||||
return this.mappings[prefix];
|
||||
}
|
||||
}
|
||||
|
||||
var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
|
||||
assert.equal('Harry Potter', xpath.selectWithResolver('//testns:title/text()', doc, resolver)[0].nodeValue);
|
||||
assert.equal('JKR', xpath.selectWithResolver('//testns:field[@type="author"]/text()', doc, resolver)[0].nodeValue);
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select xpath with namespaces, prefixes different in xml and xpath, using a resolver': function (test) {
|
||||
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var resolver = {
|
||||
mappings: {
|
||||
'ns': 'http://example.com/test'
|
||||
},
|
||||
lookupNamespaceURI: function(prefix) {
|
||||
return this.mappings[prefix];
|
||||
}
|
||||
}
|
||||
|
||||
var nodes = xpath.selectWithResolver('//ns:title/text()', doc, resolver);
|
||||
assert.equal('Harry Potter', xpath.selectWithResolver('//ns:title/text()', doc, resolver)[0].nodeValue);
|
||||
assert.equal('JKR', xpath.selectWithResolver('//ns:field[@ns:type="author"]/text()', doc, resolver)[0].nodeValue);
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'select xpath with namespaces, using namespace mappings': function (test) {
|
||||
var xml = '<book xmlns:testns="http://example.com/test"><testns:title>Harry Potter</testns:title><testns:field testns:type="author">JKR</testns:field></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var select = xpath.useNamespaces({'testns': 'http://example.com/test'});
|
||||
|
||||
assert.equal('Harry Potter', select('//testns:title/text()', doc)[0].nodeValue);
|
||||
assert.equal('JKR', select('//testns:field[@testns:type="author"]/text()', doc)[0].nodeValue);
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
|
||||
'select attribute': function (test) {
|
||||
var xml = '<author name="J. K. Rowling"></author>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var author = xpath.select1('/author/@name', doc).value;
|
||||
assert.equal('J. K. Rowling', author);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
// https://github.com/goto100/xpath/issues/37
|
||||
,'select multiple attributes': function (test) {
|
||||
var xml = '<authors><author name="J. K. Rowling" /><author name="Saeed Akl" /></authors>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var authors = xpath.select('/authors/author/@name', doc);
|
||||
assert.equal(2, authors.length);
|
||||
assert.equal('J. K. Rowling', authors[0].value);
|
||||
|
||||
// https://github.com/goto100/xpath/issues/41
|
||||
doc = new dom().parseFromString('<chapters><chapter v="1"/><chapter v="2"/><chapter v="3"/></chapters>');
|
||||
var nodes = xpath.select("/chapters/chapter/@v", doc);
|
||||
var values = nodes.map(function(n) { return n.value; });
|
||||
|
||||
assert.equal(3, values.length);
|
||||
assert.equal("1", values[0]);
|
||||
assert.equal("2", values[1]);
|
||||
assert.equal("3", values[2]);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'XPathException acts like Error': function (test) {
|
||||
try {
|
||||
xpath.evaluate('1', null, null, null);
|
||||
assert.fail(null, null, 'evaluate() should throw exception');
|
||||
} catch (e) {
|
||||
assert.ok('code' in e, 'must have a code');
|
||||
assert.ok('stack' in e, 'must have a stack');
|
||||
}
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'string() with no arguments': function (test) {
|
||||
var doc = new dom().parseFromString('<book>Harry Potter</book>');
|
||||
|
||||
var rootElement = xpath.select1('/book', doc);
|
||||
assert.ok(rootElement, 'rootElement is null');
|
||||
|
||||
assert.equal('Harry Potter', xpath.select1('string()', doc));
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'string value of document fragment': function (test) {
|
||||
var doc = new dom().parseFromString('<n />');
|
||||
var docFragment = doc.createDocumentFragment();
|
||||
|
||||
var el = doc.createElement("book");
|
||||
docFragment.appendChild(el);
|
||||
|
||||
var testValue = "Harry Potter";
|
||||
|
||||
el.appendChild(doc.createTextNode(testValue));
|
||||
|
||||
assert.equal(testValue, xpath.select1("string()", docFragment));
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'compare string of a number with a number': function (test) {
|
||||
assert.ok(xpath.select1('"000" = 0'), '000');
|
||||
assert.ok(xpath.select1('"45.0" = 45'), '45');
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'string(boolean) is a string': function (test) {
|
||||
assert.equal('string', typeof xpath.select1('string(true())'));
|
||||
assert.equal('string', typeof xpath.select1('string(false())'));
|
||||
assert.equal('string', typeof xpath.select1('string(1 = 2)'));
|
||||
assert.ok(xpath.select1('"true" = string(true())'), '"true" = string(true())');
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'string should downcast to boolean': function (test) {
|
||||
assert.equal(false, xpath.select1('"false" = false()'), '"false" = false()');
|
||||
assert.equal(true, xpath.select1('"a" = true()'), '"a" = true()');
|
||||
assert.equal(true, xpath.select1('"" = false()'), '"" = false()');
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'string(number) is a string': function (test) {
|
||||
assert.equal('string', typeof xpath.select1('string(45)'));
|
||||
assert.ok(xpath.select1('"45" = string(45)'), '"45" = string(45)');
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'correct string to number conversion': function (test) {
|
||||
assert.equal(45.2, xpath.select1('number("45.200")'));
|
||||
assert.equal(55.0, xpath.select1('number("000055")'));
|
||||
assert.equal(65.0, xpath.select1('number(" 65 ")'));
|
||||
|
||||
assert.equal(true, xpath.select1('"" != 0'), '"" != 0');
|
||||
assert.equal(false, xpath.select1('"" = 0'), '"" = 0');
|
||||
assert.equal(false, xpath.select1('0 = ""'), '0 = ""');
|
||||
assert.equal(false, xpath.select1('0 = " "'), '0 = " "');
|
||||
|
||||
assert.ok(Number.isNaN(xpath.select('number("")')), 'number("")');
|
||||
assert.ok(Number.isNaN(xpath.select('number("45.8g")')), 'number("45.8g")');
|
||||
assert.ok(Number.isNaN(xpath.select('number("2e9")')), 'number("2e9")');
|
||||
assert.ok(Number.isNaN(xpath.select('number("+33")')), 'number("+33")');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'correct number to string conversion': function (test) {
|
||||
assert.equal('0.0000000000000000000000005250000000000001', xpath.parse('0.525 div 1000000 div 1000000 div 1000000 div 1000000').evaluateString());
|
||||
assert.equal('525000000000000000000000', xpath.parse('0.525 * 1000000 * 1000000 * 1000000 * 1000000').evaluateString());
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'local-name() and name() of processing instruction': function (test) {
|
||||
var xml = '<?book-record added="2015-01-16" author="J.K. Rowling" ?><book>Harry Potter</book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var expectedName = 'book-record';
|
||||
var localName = xpath.select('local-name(/processing-instruction())', doc);
|
||||
var name = xpath.select('name(/processing-instruction())', doc);
|
||||
|
||||
assert.deepEqual(expectedName, localName, 'local-name() - "' + expectedName + '" !== "' + localName + '"');
|
||||
assert.deepEqual(expectedName, name, 'name() - "' + expectedName + '" !== "' + name + '"');
|
||||
|
||||
test.done();
|
||||
},
|
||||
|
||||
'evaluate substring-after': function (test) {
|
||||
var xml = '<classmate>Hermione</classmate>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var part = xpath.select('substring-after(/classmate, "Her")', doc);
|
||||
assert.deepEqual('mione', part);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'parsed expression with no options': function (test) {
|
||||
var parsed = xpath.parse('5 + 7');
|
||||
|
||||
assert.equal(typeof parsed, "object", "parse() should return an object");
|
||||
assert.equal(typeof parsed.evaluate, "function", "parsed.evaluate should be a function");
|
||||
assert.equal(typeof parsed.evaluateNumber, "function", "parsed.evaluateNumber should be a function");
|
||||
|
||||
assert.equal(parsed.evaluateNumber(), 12);
|
||||
|
||||
// evaluating twice should yield the same result
|
||||
assert.equal(parsed.evaluateNumber(), 12);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'select1() on parsed expression': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var parsed = xpath.parse('/*/title');
|
||||
|
||||
assert.equal(typeof parsed, 'object', 'parse() should return an object');
|
||||
|
||||
assert.equal(typeof parsed.select1, 'function', 'parsed.select1 should be a function');
|
||||
|
||||
var single = parsed.select1({ node: doc });
|
||||
|
||||
assert.equal('title', single.localName);
|
||||
assert.equal('Harry Potter', single.firstChild.data);
|
||||
assert.equal('<title>Harry Potter</title>', single.toString());
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'select() on parsed expression': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var parsed = xpath.parse('/*/title');
|
||||
|
||||
assert.equal(typeof parsed, 'object', 'parse() should return an object');
|
||||
|
||||
assert.equal(typeof parsed.select, 'function', 'parsed.select should be a function');
|
||||
|
||||
var nodes = parsed.select({ node: doc });
|
||||
|
||||
assert.ok(nodes, 'parsed.select() should return a value');
|
||||
assert.equal(1, nodes.length);
|
||||
assert.equal('title', nodes[0].localName);
|
||||
assert.equal('Harry Potter', nodes[0].firstChild.data);
|
||||
assert.equal('<title>Harry Potter</title>', nodes[0].toString());
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'evaluateString(), and evaluateNumber() on parsed expression with node': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title><numVolumes>7</numVolumes></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var parsed = xpath.parse('/*/numVolumes');
|
||||
|
||||
assert.equal(typeof parsed, 'object', 'parse() should return an object');
|
||||
|
||||
assert.equal(typeof parsed.evaluateString, 'function', 'parsed.evaluateString should be a function');
|
||||
assert.equal('7', parsed.evaluateString({ node: doc }));
|
||||
|
||||
assert.equal(typeof parsed.evaluateBoolean, 'function', 'parsed.evaluateBoolean should be a function');
|
||||
assert.equal(true, parsed.evaluateBoolean({ node: doc }));
|
||||
|
||||
assert.equal(typeof parsed.evaluateNumber, 'function', 'parsed.evaluateNumber should be a function');
|
||||
assert.equal(7, parsed.evaluateNumber({ node: doc }));
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'evaluateBoolean() on parsed empty node set and boolean expressions': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var context = { node: doc };
|
||||
|
||||
function evaluate(path) {
|
||||
return xpath.parse(path).evaluateBoolean({ node: doc });
|
||||
}
|
||||
|
||||
assert.equal(false, evaluate('/*/myrtle'), 'boolean value of empty node set should be false');
|
||||
|
||||
assert.equal(true, evaluate('not(/*/myrtle)'), 'not() of empty nodeset should be true');
|
||||
|
||||
assert.equal(true, evaluate('/*/title'), 'boolean value of non-empty nodeset should be true');
|
||||
|
||||
assert.equal(true, evaluate('/*/title = "Harry Potter"'), 'title equals Harry Potter');
|
||||
|
||||
assert.equal(false, evaluate('/*/title != "Harry Potter"'), 'title != Harry Potter should be false');
|
||||
|
||||
assert.equal(false, evaluate('/*/title = "Percy Jackson"'), 'title should not equal Percy Jackson');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'namespaces with parsed expression': function (test) {
|
||||
var xml = '<characters xmlns:ps="http://philosophers-stone.com" xmlns:cs="http://chamber-secrets.com">' +
|
||||
'<ps:character>Quirrell</ps:character><ps:character>Fluffy</ps:character>' +
|
||||
'<cs:character>Myrtle</cs:character><cs:character>Tom Riddle</cs:character>' +
|
||||
'</characters>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var expr = xpath.parse('/characters/c:character');
|
||||
var countExpr = xpath.parse('count(/characters/c:character)');
|
||||
var csns = 'http://chamber-secrets.com';
|
||||
|
||||
function resolve(prefix) {
|
||||
if (prefix === 'c') {
|
||||
return csns;
|
||||
}
|
||||
}
|
||||
|
||||
function testContext(context, description) {
|
||||
try {
|
||||
var value = expr.evaluateString(context);
|
||||
var count = countExpr.evaluateNumber(context);
|
||||
|
||||
assert.equal('Myrtle', value, description + ' - string value - ' + value);
|
||||
assert.equal(2, count, description + ' map - count - ' + count);
|
||||
} catch(e) {
|
||||
e.message = description + ': ' + (e.message || '');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
namespaces: {
|
||||
c: csns
|
||||
}
|
||||
}, 'Namespace map');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
namespaces: resolve
|
||||
}, 'Namespace function');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
namespaces: {
|
||||
getNamespace: resolve
|
||||
}
|
||||
}, 'Namespace object');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'custom functions': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var parsed = xpath.parse('concat(double(/*/title), " is cool")');
|
||||
|
||||
function doubleString(context, value) {
|
||||
assert.equal(2, arguments.length);
|
||||
var str = value.stringValue();
|
||||
return str + str;
|
||||
}
|
||||
|
||||
function functions(name, namespace) {
|
||||
if(name === 'double') {
|
||||
return doubleString;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function testContext(context, description) {
|
||||
try{
|
||||
var actual = parsed.evaluateString(context);
|
||||
var expected = 'Harry PotterHarry Potter is cool';
|
||||
assert.equal(expected, actual, description + ' - ' + expected + ' != ' + actual);
|
||||
} catch (e) {
|
||||
e.message = description + ": " + (e.message || '');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
functions: functions
|
||||
}, 'Functions function');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
functions: {
|
||||
getFunction: functions
|
||||
}
|
||||
}, 'Functions object');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
functions: {
|
||||
double: doubleString
|
||||
}
|
||||
}, 'Functions map');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'custom function namespaces': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title><friend>Ron</friend><friend>Hermione</friend><friend>Neville</friend></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var parsed = xpath.parse('concat(hp:double(/*/title), " is 2 cool ", hp:square(2), " school")');
|
||||
var hpns = 'http://harry-potter.com';
|
||||
|
||||
var namespaces = {
|
||||
hp: hpns
|
||||
};
|
||||
|
||||
var context = {
|
||||
node: doc,
|
||||
namespaces: {
|
||||
hp: hpns
|
||||
},
|
||||
functions: function (name, namespace) {
|
||||
if (namespace === hpns) {
|
||||
switch (name) {
|
||||
case "double":
|
||||
return function (context, value) {
|
||||
assert.equal(2, arguments.length);
|
||||
var str = value.stringValue();
|
||||
return str + str;
|
||||
};
|
||||
case "square":
|
||||
return function (context, value) {
|
||||
var num = value.numberValue();
|
||||
return num * num;
|
||||
};
|
||||
|
||||
case "xor":
|
||||
return function (context, l, r) {
|
||||
assert.equal(3, arguments.length);
|
||||
var lbool = l.booleanValue();
|
||||
var rbool = r.booleanValue();
|
||||
return (lbool || rbool) && !(lbool && rbool);
|
||||
};
|
||||
|
||||
case "second":
|
||||
return function (context, nodes) {
|
||||
var nodesArr = nodes.toArray();
|
||||
var second = nodesArr[1];
|
||||
return second ? [second] : [];
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
assert.equal('Harry PotterHarry Potter is 2 cool 4 school', parsed.evaluateString(context));
|
||||
|
||||
assert.equal(false, xpath.parse('hp:xor(false(), false())').evaluateBoolean(context));
|
||||
assert.equal(true, xpath.parse('hp:xor(false(), true())').evaluateBoolean(context));
|
||||
assert.equal(true, xpath.parse('hp:xor(true(), false())').evaluateBoolean(context));
|
||||
assert.equal(false, xpath.parse('hp:xor(true(), true())').evaluateBoolean(context));
|
||||
|
||||
assert.equal('Hermione', xpath.parse('hp:second(/*/friend)').evaluateString(context));
|
||||
assert.equal(1, xpath.parse('count(hp:second(/*/friend))').evaluateNumber(context));
|
||||
assert.equal(0, xpath.parse('count(hp:second(/*/friendz))').evaluateNumber(context));
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'xpath variables': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title><volumes>7</volumes></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
|
||||
var variables = {
|
||||
title: 'Harry Potter',
|
||||
notTitle: 'Percy Jackson',
|
||||
houses: 4
|
||||
};
|
||||
|
||||
function variableFunction(name) {
|
||||
return variables[name];
|
||||
}
|
||||
|
||||
function testContext(context, description) {
|
||||
try{
|
||||
assert.equal(true, xpath.parse('$title = /*/title').evaluateBoolean(context));
|
||||
assert.equal(false, xpath.parse('$notTitle = /*/title').evaluateBoolean(context));
|
||||
assert.equal(11, xpath.parse('$houses + /*/volumes').evaluateNumber(context));
|
||||
} catch (e) {
|
||||
e.message = description + ": " + (e.message || '');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
variables: variableFunction
|
||||
}, 'Variables function');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
variables: {
|
||||
getVariable: variableFunction
|
||||
}
|
||||
}, 'Variables object');
|
||||
|
||||
testContext({
|
||||
node: doc,
|
||||
variables: variables
|
||||
}, 'Variables map');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'xpath variable namespaces': function (test) {
|
||||
var xml = '<book><title>Harry Potter</title><volumes>7</volumes></book>';
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var hpns = 'http://harry-potter.com';
|
||||
|
||||
var context = {
|
||||
node: doc,
|
||||
namespaces: {
|
||||
hp: hpns
|
||||
},
|
||||
variables: function(name, namespace) {
|
||||
if (namespace === hpns) {
|
||||
switch (name) {
|
||||
case 'title': return 'Harry Potter';
|
||||
case 'houses': return 4;
|
||||
case 'false': return false;
|
||||
case 'falseStr': return 'false';
|
||||
}
|
||||
} else if (namespace === '') {
|
||||
switch (name) {
|
||||
case 'title': return 'World';
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
assert.equal(true, xpath.parse('$hp:title = /*/title').evaluateBoolean(context));
|
||||
assert.equal(false, xpath.parse('$title = /*/title').evaluateBoolean(context));
|
||||
assert.equal('World', xpath.parse('$title').evaluateString(context));
|
||||
assert.equal(false, xpath.parse('$hp:false').evaluateBoolean(context));
|
||||
assert.notEqual(false, xpath.parse('$hp:falseStr').evaluateBoolean(context));
|
||||
assert.throws(function () {
|
||||
xpath.parse('$hp:hello').evaluateString(context);
|
||||
}, function (err) {
|
||||
return err.message === 'Undeclared variable: $hp:hello';
|
||||
});
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"detect unterminated string literals": function (test) {
|
||||
function testUnterminated(path) {
|
||||
assert.throws(function () {
|
||||
xpath.evaluate('"hello');
|
||||
}, function (err) {
|
||||
return err.message.indexOf('Unterminated') !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
testUnterminated('"Hello');
|
||||
testUnterminated("'Hello");
|
||||
testUnterminated('self::text() = "\""');
|
||||
testUnterminated('"\""');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"string value for CDATA sections": function (test) {
|
||||
var xml = "<people><person><![CDATA[Harry Potter]]></person><person>Ron <![CDATA[Weasley]]></person></people>",
|
||||
doc = new dom().parseFromString(xml),
|
||||
person1 = xpath.parse("/people/person").evaluateString({ node: doc }),
|
||||
person2 = xpath.parse("/people/person/text()").evaluateString({ node: doc }),
|
||||
person3 = xpath.select("string(/people/person/text())", doc);
|
||||
person4 = xpath.parse("/people/person[2]").evaluateString({ node: doc });
|
||||
|
||||
assert.equal(person1, 'Harry Potter');
|
||||
assert.equal(person2, 'Harry Potter');
|
||||
assert.equal(person3, 'Harry Potter');
|
||||
assert.equal(person4, 'Ron Weasley');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"string value of various node types": function (test) {
|
||||
var xml = "<book xmlns:hp='http://harry'><!-- This describes the Harry Potter Book --><?author name='J.K. Rowling' ?><title lang='en'><![CDATA[Harry Potter & the Philosopher's Stone]]></title><character>Harry Potter</character></book>",
|
||||
doc = new dom().parseFromString(xml),
|
||||
allText = xpath.parse('.').evaluateString({ node: doc }),
|
||||
ns = xpath.parse('*/namespace::*[name() = "hp"]').evaluateString({ node: doc }),
|
||||
title = xpath.parse('*/title').evaluateString({ node: doc }),
|
||||
child = xpath.parse('*/*').evaluateString({ node: doc }),
|
||||
titleLang = xpath.parse('*/*/@lang').evaluateString({ node: doc }),
|
||||
pi = xpath.parse('*/processing-instruction()').evaluateString({ node: doc }),
|
||||
comment = xpath.parse('*/comment()').evaluateString({ node: doc });
|
||||
|
||||
assert.equal(allText, "Harry Potter & the Philosopher's StoneHarry Potter");
|
||||
assert.equal(ns, 'http://harry');
|
||||
assert.equal(title, "Harry Potter & the Philosopher's Stone");
|
||||
assert.equal(child, "Harry Potter & the Philosopher's Stone");
|
||||
assert.equal(titleLang, 'en');
|
||||
assert.equal(pi.trim(), "name='J.K. Rowling'");
|
||||
assert.equal(comment, ' This describes the Harry Potter Book ');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"exposes custom types": function (test) {
|
||||
assert.ok(xpath.XPath, "xpath.XPath");
|
||||
assert.ok(xpath.XPathParser, "xpath.XPathParser");
|
||||
assert.ok(xpath.XPathResult, "xpath.XPathResult");
|
||||
|
||||
assert.ok(xpath.Step, "xpath.Step");
|
||||
assert.ok(xpath.NodeTest, "xpath.NodeTest");
|
||||
assert.ok(xpath.BarOperation, "xpath.BarOperation");
|
||||
|
||||
assert.ok(xpath.NamespaceResolver, "xpath.NamespaceResolver");
|
||||
assert.ok(xpath.FunctionResolver, "xpath.FunctionResolver");
|
||||
assert.ok(xpath.VariableResolver, "xpath.VariableResolver");
|
||||
|
||||
assert.ok(xpath.Utilities, "xpath.Utilities");
|
||||
|
||||
assert.ok(xpath.XPathContext, "xpath.XPathContext");
|
||||
assert.ok(xpath.XNodeSet, "xpath.XNodeSet");
|
||||
assert.ok(xpath.XBoolean, "xpath.XBoolean");
|
||||
assert.ok(xpath.XString, "xpath.XString");
|
||||
assert.ok(xpath.XNumber, "xpath.XNumber");
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"work with nodes created using DOM1 createElement()": function (test) {
|
||||
var doc = new dom().parseFromString('<book />');
|
||||
|
||||
doc.documentElement.appendChild(doc.createElement('characters'));
|
||||
|
||||
assert.ok(xpath.select1('/book/characters', doc));
|
||||
|
||||
assert.equal(xpath.select1('local-name(/book/characters)', doc), 'characters');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"preceding:: axis works on document fragments": function (test) {
|
||||
var doc = new dom().parseFromString('<n />'),
|
||||
df = doc.createDocumentFragment(),
|
||||
root = doc.createElement('book');
|
||||
|
||||
df.appendChild(root);
|
||||
|
||||
for (var i = 0; i < 10; i += 1) {
|
||||
root.appendChild(doc.createElement('chapter'));
|
||||
}
|
||||
|
||||
var chapter = xpath.select1("book/chapter[5]", df);
|
||||
|
||||
assert.ok(chapter, 'chapter');
|
||||
|
||||
assert.equal(xpath.select("count(preceding::chapter)", chapter), 4);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,"node set sorted and unsorted arrays": function (test) {
|
||||
var doc = new dom().parseFromString('<book><character>Harry</character><character>Ron</character><character>Hermione</character></book>'),
|
||||
path = xpath.parse("/*/*[3] | /*/*[2] | /*/*[1]")
|
||||
nset = path.evaluateNodeSet({ node: doc }),
|
||||
sorted = nset.toArray(),
|
||||
unsorted = nset.toUnsortedArray();
|
||||
|
||||
assert.equal(sorted.length, 3);
|
||||
assert.equal(unsorted.length, 3);
|
||||
|
||||
assert.equal(sorted[0].textContent, 'Harry');
|
||||
assert.equal(sorted[1].textContent, 'Ron');
|
||||
assert.equal(sorted[2].textContent, 'Hermione');
|
||||
|
||||
assert.notEqual(sorted[0], unsorted[0], "first nodeset element equal");
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'meaningful error for invalid function': function(test) {
|
||||
var path = xpath.parse('invalidFunc()');
|
||||
|
||||
assert.throws(function () {
|
||||
path.evaluateString();
|
||||
}, function (err) {
|
||||
return err.message.indexOf('invalidFunc') !== -1;
|
||||
});
|
||||
|
||||
var path2 = xpath.parse('funcs:invalidFunc()');
|
||||
|
||||
assert.throws(function () {
|
||||
path2.evaluateString({
|
||||
namespaces: {
|
||||
funcs: 'myfunctions'
|
||||
}
|
||||
});
|
||||
}, function (err) {
|
||||
return err.message.indexOf('invalidFunc') !== -1;
|
||||
});
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
// https://github.com/goto100/xpath/issues/32
|
||||
,'supports contains() function on attributes': function (test) {
|
||||
var doc = new dom().parseFromString("<books><book title='Harry Potter and the Philosopher\"s Stone' /><book title='Harry Potter and the Chamber of Secrets' /></books>"),
|
||||
andTheBooks = xpath.select("/books/book[contains(@title, ' ')]", doc),
|
||||
secretBooks = xpath.select("/books/book[contains(@title, 'Secrets')]", doc);
|
||||
|
||||
assert.equal(andTheBooks.length, 2);
|
||||
assert.equal(secretBooks.length, 1);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'compare multiple nodes to multiple nodes (equals)': function (test) {
|
||||
var xml = '<school><houses>' +
|
||||
'<house name="Gryffindor"><student>Harry</student><student>Hermione</student></house>' +
|
||||
'<house name="Slytherin"><student>Draco</student><student>Crabbe</student></house>' +
|
||||
'<house name="Ravenclaw"><student>Luna</student><student>Cho</student></house>' +
|
||||
'</houses>' +
|
||||
'<honorStudents><student>Hermione</student><student>Luna</student></honorStudents></school>';
|
||||
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var houses = xpath.parse('/school/houses/house[student = /school/honorStudents/student]').select({ node: doc });
|
||||
|
||||
assert.equal(houses.length, 2);
|
||||
|
||||
var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
|
||||
|
||||
assert.equal(houseNames[0], 'Gryffindor');
|
||||
assert.equal(houseNames[1], 'Ravenclaw');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
,'compare multiple nodes to multiple nodes (gte)': function (test) {
|
||||
var xml = '<school><houses>' +
|
||||
'<house name="Gryffindor"><student level="5">Harry</student><student level="9">Hermione</student></house>' +
|
||||
'<house name="Slytherin"><student level="1">Goyle</student><student level="1">Crabbe</student></house>' +
|
||||
'<house name="Ravenclaw"><student level="4">Luna</student><student level="3">Cho</student></house>' +
|
||||
'</houses>' +
|
||||
'<courses><course minLevel="9">DADA</course><course minLevel="4">Charms</course></courses>' +
|
||||
'</school>';
|
||||
|
||||
var doc = new dom().parseFromString(xml);
|
||||
var houses = xpath.parse('/school/houses/house[student/@level >= /school/courses/course/@minLevel]').select({ node: doc });
|
||||
|
||||
assert.equal(houses.length, 2);
|
||||
|
||||
var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
|
||||
|
||||
assert.equal(houseNames[0], 'Gryffindor');
|
||||
assert.equal(houseNames[1], 'Ravenclaw');
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
}
|
||||
9
static/js/ketcher2/node_modules/xpath/xpath.d.ts
generated
vendored
Normal file
9
static/js/ketcher2/node_modules/xpath/xpath.d.ts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
type SelectedValue = Node | Attr | string | number | boolean;
|
||||
interface XPathSelect {
|
||||
(expression: string, node?: Node): Array<SelectedValue>;
|
||||
(expression: string, node: Node, single: true): SelectedValue;
|
||||
}
|
||||
export var select: XPathSelect;
|
||||
export function select1(expression: string, node?: Node): SelectedValue;
|
||||
export function evaluate(expression: string, contextNode: Node, resolver: XPathNSResolver, type: number, result: XPathResult): XPathResult;
|
||||
export function useNamespaces(namespaceMap: { [name: string]: string }): XPathSelect;
|
||||
4728
static/js/ketcher2/node_modules/xpath/xpath.js
generated
vendored
Normal file
4728
static/js/ketcher2/node_modules/xpath/xpath.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user