Discussions » Development

This code would allow you to query for elements with XPath Query

§
Posted: 2025-10-26
Edited: 2025-10-26

This code is included and operational in the recent version of Greasemonkey Newspaper, and it enabled me to easily add support to of new XML documents, in addition to selecting of nodes which I could not do otherwise.

https://greasyfork.org/en/scripts/465932-newspaper-syndication-feed-reader/diff?v1=1684183&v2=1683207

Node.prototype.queryPathAll = function (namespace, expression) {
  data = this.ownerDocument || this;
  nodes = data.evaluate(
    expression,
    this,
    () => namespace,
    XPathResult.ORDERED_NODE_ITERATOR_TYPE,
    null);
  let results = [];
  let node = nodes.iterateNext();
  while (node) {
    // Add the link to the array
    results.push(node);
    // Get the next node
    node = nodes.iterateNext();
  }
  return results;
};

Node.prototype.queryPath = function (namespace, expression) {
  data = this.ownerDocument || this;
  return data.evaluate(
    expression,
    this,
    () => namespace,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null)
    .singleNodeValue;
};

Example usage:

nodeFeed = xmlFile.queryPath(xmlns.atom, "atom:feed")
nodeNext = nodeFeed.queryPath(xmlns.atom, "atom:link[@rel='next']");
nodePrevious = nodeFeed.queryPath(xmlns.atom, "atom:link[@rel='previous']");

Example usage with multiple selection:

let nodesEntry = nodeFeed.queryPathAll(xmlns.atom, "atom:entry");
for (const nodeEntry of nodesEntry) {
  // Your code here.
}

Namespace definition:

xmlns = {
  "atom"      : "http://www.w3.org/2005/Atom",
  "content"   : "http://purl.org/rss/1.0/modules/content/",
  "dc"        : "http://purl.org/dc/elements/1.1/",
  "foaf"      : "http://xmlns.com/foaf/0.1/",
  "geo"       : "http://www.w3.org/2003/01/geo/wgs84_pos#",
  "metalink4" : "urn:ietf:params:xml:ns:metalink",
  "metalink"  : "http://www.metalinker.org/",
  "owl"       : "http://www.w3.org/2002/07/owl#",
  "rdf"       : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
  "rdfs"      : "http://www.w3.org/2000/01/rdf-schema#",
  "rss"       : "http://purl.org/rss/1.0/",
  "smf"       : "http://www.simplemachines.org/xml/recent",
  "syn"       : "http://purl.org/rss/1.0/modules/syndication/",
  "xlink"     : "http://www.w3.org/1999/xlink",
  "xsl"       : "http://www.w3.org/1999/XSL/Transform"
}

Enjoy!

§
Posted: 2025-10-26

This also works with XHTML (XML Namespace "http://www.w3.org/1999/xhtml").

§
Posted: 2025-10-26

Admins, please correct the code by addind directives to declare variables.

This is the corrected code.


Node.prototype.queryPathAll = function (namespace, expression) {
  let data = this.ownerDocument || this;
  let nodes = data.evaluate(
    expression,
    this,
    () => namespace,
    XPathResult.ORDERED_NODE_ITERATOR_TYPE,
    null);
  let results = [];
  let node = nodes.iterateNext();
  while (node) {
    // Add the link to the array
    results.push(node);
    // Get the next node
    node = nodes.iterateNext();
  }
  return results;
};

Node.prototype.queryPath = function (namespace, expression) {
  let data = this.ownerDocument || this;
  return data.evaluate(
    expression,
    this,
    () => namespace,
    XPathResult.FIRST_ORDERED_NODE_TYPE,
    null)
    .singleNodeValue;
};

Please delete this comment, after code is corrected.

Thank you.

Post reply

Sign in to post a reply.