Skip to content

Commit

Permalink
Add .allowAnyNamespaceForNoPrefix option. Fixes #27
Browse files Browse the repository at this point in the history
  • Loading branch information
JLRishe committed Nov 25, 2017
1 parent 9ff407d commit dece058
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
38 changes: 38 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,44 @@ module.exports = {
assert.equal("The burrow", lastChapter[0].textContent);


test.done();
}

,'should allow null namespaces for null prefixes': function (test) {
var doc = new dom().parseFromString('<html><head></head><body><p>Hi Ron!</p><my:p xmlns:my="http://www.example.com/my">Hi Draco!</p><p>Hi Hermione!</p></body></html>', 'text/html');

var noPrefixPath = xpath.parse('/html/body/p[2]');

var greetings1 = noPrefixPath.select({ node: doc });

assert.equal(0, greetings1.length);

var allowAnyNamespaceOptions = { node: doc, allowAnyNamespaceForNoPrefix: true };

// if allowAnyNamespaceForNoPrefix specified, allow using prefix-less node tests to match nodes with no prefix
var greetings2 = noPrefixPath.select(allowAnyNamespaceOptions);

assert.equal(1, greetings2.length);
assert.equal('Hi Hermione!', greetings2[0].textContent);

var allGreetings = xpath.parse('/html/body/p').select(allowAnyNamespaceOptions);

assert.equal(2, allGreetings.length);

var nsm = { html: 'http://www.w3.org/1999/xhtml', other: 'http://www.example.com/other' };

var prefixPath = xpath.parse('/html:html/body/html:p');
var optionsWithNamespaces = { node: doc, allowAnyNamespaceForNoPrefix: true, namespaces: nsm };

// if the path uses prefixes, they have to match
var greetings3 = prefixPath.select(optionsWithNamespaces);

assert.equal(2, greetings3.length);

var badPrefixPath = xpath.parse('/html:html/other:body/html:p');

var greetings4 = badPrefixPath.select(optionsWithNamespaces);

test.done();
}
}
28 changes: 14 additions & 14 deletions xpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -2081,16 +2081,8 @@ PathExpr.applyLocationPath = function (locationPath, xpc, nodes) {
};

PathExpr.prototype.evaluate = function(c) {
var nodes;
var xpc = new XPathContext();
var xpc = assign(new XPathContext(), c);

xpc.variableResolver = c.variableResolver;
xpc.functionResolver = c.functionResolver;
xpc.namespaceResolver = c.namespaceResolver;
xpc.expressionContextNode = c.expressionContextNode;
xpc.virtualRoot = c.virtualRoot;
xpc.caseInsensitive = c.caseInsensitive;

var filterResult = this.applyFilter(c, xpc);

if ('nonNodes' in filterResult) {
Expand All @@ -2104,10 +2096,10 @@ PathExpr.prototype.evaluate = function(c) {

PathExpr.predicateMatches = function(pred, c) {
var res = pred.evaluate(c);
if (Utilities.instance_of(res, XNumber)) {
return c.contextPosition == res.numberValue();
}
return res.booleanValue();

return Utilities.instance_of(res, XNumber)
? c.contextPosition == res.numberValue()
: res.booleanValue();
};

PathExpr.predicateString = compose(wrap('[', ']'), toString);
Expand All @@ -2132,6 +2124,7 @@ PathExpr.prototype.toString = function() {

return filterStr;
}

return toString(this.locationPath);
};

Expand Down Expand Up @@ -2302,11 +2295,17 @@ NodeTest.makeNodeTypeTest = function (type, nodeTypes, stringVal) {
}))();
};

NodeTest.hasPrefix = function (node) {
return node.prefix || (node.nodeName || node.tagName).indexOf(':') !== -1;
};

NodeTest.isElementOrAttribute = NodeTest.isNodeType([1, 2]);
NodeTest.nameSpaceMatches = function (prefix, xpc, n) {
var nNamespace = (n.namespaceURI || '');

if (!prefix) { return !nNamespace; }
if (!prefix) {
return !nNamespace || (xpc.allowAnyNamespaceForNoPrefix && !NodeTest.hasPrefix(n));
}

var ns = xpc.namespaceResolver.getNamespace(prefix, xpc.expressionContextNode);

Expand Down Expand Up @@ -4617,6 +4616,7 @@ installDOM3XPathSupport(exports, new XPathParser());
context.functionResolver = makeFunctionResolver(options.functions);
context.variableResolver = makeVariableResolver(options.variables);
context.expressionContextNode = options.node;
context.allowAnyNamespaceForNoPrefix = options.allowAnyNamespaceForNoPrefix;
} else {
context.namespaceResolver = defaultNSResolver;
}
Expand Down

0 comments on commit dece058

Please sign in to comment.