{"id":20331097,"url":"https://github.com/comcast/xml-selector","last_synced_at":"2025-04-11T21:07:15.410Z","repository":{"id":25590510,"uuid":"29024832","full_name":"Comcast/xml-selector","owner":"Comcast","description":"A jQuery-like interface for working with XML using CSS-style selectors","archived":false,"fork":false,"pushed_at":"2015-04-20T18:49:44.000Z","size":290,"stargazers_count":12,"open_issues_count":1,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-09T10:41:27.018Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Comcast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-09T16:33:03.000Z","updated_at":"2023-06-21T00:50:02.000Z","dependencies_parsed_at":"2022-08-23T09:11:08.647Z","dependency_job_id":null,"html_url":"https://github.com/Comcast/xml-selector","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Comcast%2Fxml-selector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Comcast%2Fxml-selector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Comcast%2Fxml-selector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Comcast%2Fxml-selector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Comcast","download_url":"https://codeload.github.com/Comcast/xml-selector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224684980,"owners_count":17352660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T20:18:44.394Z","updated_at":"2024-11-14T20:18:45.261Z","avatar_url":"https://github.com/Comcast.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XML Selector\n\nXML Selector is a utility for working with XML. It provides partial DOM\nsupport and a jQuery-like interface for traversing XML documents using\nCSS-style selectors.\n\nPlease note that as of version 0.3 XML Selector uses its own DOM\nimplementation based on [libxml2](http://xmlsoft.org). This is different\nthan the previous non-standard document interface. XML Selector currently\nimplements a read-only subset of DOM Level 1. This will be extended in\nthe future to meet, at minimum, full Level 1 support.\n\n## Why Should I Use This Thing?\n\n### The TL;DR Version\n\nBecause you want a fast, mature XML parser, and you want to write less\ncode without hassling with a lot of complexity.\n\nPlus, we've thought through things like namespaces, so it will be\npossible to do what you need to, no matter how crazy the XML you're\ndealing with is, and the most common cases should just work.\n\n### The Longer Version\n\nXML Selector provides an interface for efficiently and accurately working\nwith XML documents. To get a sense of how it helps save you coding time,\nconsider the following XML document:\n\n```xml\n\u003cdocument\u003e\n  \u003clist\u003e\n    \u003citem type=\"greeting\"\u003eHello\u003c/item\u003e\n    \u003citem type=\"punctuation\"\u003e,\u003c/item\u003e\n    \u003citem type=\"space\" /\u003e\n    \u003citem type=\"object\"\u003eworld\u003c/item\u003e\n    \u003citem type=\"punctuation\"\u003e!\u003c/item\u003e\n  \u003c/list\u003e\n\u003c/document\u003e\n```\n\nLet's say you want to grab the greeting item text and the object item\ntext out of this document. If you're using the DOM, it's not exactly a\ntrivial exercise:\n\n```javascript\nfunction find(nodeList, testFunction) {\n  for (var i = 0; i \u003c nodeList.length; i++)\n    if (testFunction(nodeList[i], i, nodeList))\n      return nodeList[i];\n}\n\nvar items = document.getElementsByName('item');\n\nvar greeting = find(items, function(i) { return i.getAttribute('type') === 'greeting'; });\nvar object = find(items, function(i) { return i.getAttribute('type') === 'object'; });\n\nvar greetingText = greeting ? greeting.textContent : undefined;\nvar objectText = object ? object.textContent : undefined;\n\nconsole.log(\"greeting=%s object=%s\", greetingText, objectText);\n```\n\nUsing XML Selector, this becomes:\n\n```javascript\nconsole.log(\"greeting=%s object=%s\",\n  $doc.find('item[type=\"greeting\"]').text(),\n  $doc.find('item[type=\"object\"]').text());\n```\nwhere `$doc` is the document in an XMLSelector instance.\n\n#### But Isn't *Another Alternate Solution* Just As Good?\n\nTo be sure, there are a number of other viable solutions out there for\neasily working with XML, but there are three big advantages that XML\nSelector offers:\n\n1. Selectors are simple but powerful\n\n   The selector syntax is very simple and quick to pick up. If you know\n   CSS, you already know the syntax. If you don't, you can pick it up in\n   its entirety in a few minutes. Other technologies like XPath involve a\n   steeper learning curve.\n\n1. Simplicity doesn't come at the cost of information loss\n\n   Some utilities simplify working with XML by converting the document\n   into a native data structure (e.g. mapping element names to properties\n   on an object). Unfortunately, this tends to involve information loss\n   since native data structures generally don't have corollaries for both\n   named attributes and named child elements. In the case of namespaces,\n   ambiguities tend to arise. XML Selector has the advantage of preserving\n   all of the underlying XML document, but making it simpler to find the\n   portion you're looking for.\n\n1. No stopping to check for null in the middle\n\n   XML Selector follows jQuery's pattern of providing a collection of\n   operations for sets that can be chained together. Since you're working\n   with sets, there isn't a need to check for nulls or no results in the\n   middle of the chain (no results just yield an empty set instead of a\n   null). That frees you up to build a concise set of operations and, if\n   needed, check for success or failure at the end.\n\n## Getting Started\n\nTo start using the library, require the module, and create a new instance\nwith a string of XML or by giving it any number of nodes:\n\n```javascript\nvar $$ = require('xml-selector');\n\nvar xmlStr = '\u003citems\u003e' +\n               '\u003citem\u003e\u003cvalue\u003eZero\u003c/value\u003e\u003c/item\u003e' +\n               '\u003citem\u003e\u003cvalue\u003eOne\u003c/value\u003e\u003c/item\u003e' +\n               '\u003citem\u003e\u003cvalue\u003eTwo\u003c/value\u003e\u003c/item\u003e' +\n             '\u003c/items\u003e';\n\nvar $doc = $$(xmlStr);\n\n// or\n\nvar doc = $$.parseFromString(xmlStr);\nvar item = doc.documentElement.firstChild;\n\nvar $doc2 = $$(item, item.nextSibling, item.nextSibling.nextSibling);\n```\n\nIf you're already familiar with jQuery, that may be all you need to get\nstarted. Feel free to jump ahead to the [API](#section_api)\nto see exactly what's supported.\n\n### Working With Selectors\n\nXML Selector currently supports a subset of CSS selectors. The list of\ncurrently supported selectors is shown below.\n\n * __\\*__\n   matches any element\n * **E**\n   matches any *E* element\n * **E F**\n   matches any *F* element that is a descendant of an *E* element\n * **E \u003e F**\n   matches any *F* element that is a child of an *E* element\n * **E + F**\n   matches any *F* element whose previous element sibling is an *E* element\n * **E[foo=\"warning\"]**\n   matches any *E* element whose *foo* attribute is exactly equal to *\"warning\"*.\n\nIf you're not already familiar with CSS selectors, the rules are pretty\nsimple. A selector with just a name: `\"item\"` will search the document\n(or current context) for all elements with that name. So, that selector\nwould return all of the `item` elements from the document in our example\nat the start of this page.\n\nYou can combine multiple names for more complex searches. Separating the\nnames with only a space means any number of elements may come between\nthose, but the elements to the right must be descendants of those to the\nleft. So, a selector like `\"document item\"` would also match all of the\n`item` elements in our example at top since all of those elements are\ndescendants of the `document` element. The `items` element that comes\nbetween them doesn't have to appear in the selector because the space\nseparator doesn't require the elements to be direct descendants.\n\nThe `\u003e` combinator, however, does require elements to be direct\ndescendants. So a selector of `\"document \u003e item\"` wouldn't match anything\nin our example. A selector of either `\"items \u003e item\"` or\n`\"document \u003e items \u003e item\"` would match those same `item` elements.\n\nYou can further limit elements that match by specifying attribute values\nin square brackets. As shown in the example code in the introduction, you\ncan limit the item elements to specific types, for example, only type\nattributes with a value of `\"greeting\"`, like so:\n`'item[type=\"greeting\"]'`.\n\nA second combinator, the `+` sign, can also be used to specify a different\nrelationship between elements. That symbol requires the matching element\non the right to be the next sibling of the element on the left of the `+`\nsign. So, a selector like `'item[type=\"space\"] + item'` would match the\n`\u003citem type=\"object\"\u003eworld\u003c/item\u003e` element, since it is the next sibling\nof the space type item.\n\nLastly, `*` matches any element. By itself it can be used to return every\nelement in the document. It's most useful, though, for expressions where\nyou may want to match multiple element names, such any element of type\npunctuation: `'*[type=\"punctuation\"]'` or any next sibling of an item\nelement: `\"item + *\"`.\n\n### Namespaces\n\nNamespaces are frequently a source of problems. The flexibility of\ndeclaring namespaces in different ways in XML combines with varying\nsupport in available XML tools to create a whole lot of headache for\ndevelopers.\n\nConsider the following XML. This is a simplified document similar to a\nreal-life API response I once encountered:\n\n```xml\n\u003cfoo:ApiResponse xmlns:foo=\"urn:acmecompany:foo:api:v1.0\" version=\"1.0\"\u003e\n \u003cfoo:Status Code=\"urn:acmecompany:foo:api:rest:1.0:status:Incorrect\" Message=\"\" /\u003e\n\u003c/foo:ApiResponse\u003e\n```\n\nThat's what an invalid response looks like. Now consider the\ncorresponding valid response:\n\n```xml\n\u003cApiResponse xmlns=\"urn:acmecompany:foo:api:v1.0\" version=\"1.0\"\u003e\n  \u003cValue\u003e\u003c!-- some result here --\u003e\u003c/Value\u003e\n  \u003cStatus Code=\"urn:acmecompany:foo:api:rest:1.0:status:Success\"/\u003e\n\u003c/ApiResponse\u003e\n```\n\nBoth of these documents have all elements in the same namespace\n(urn:acmecompany:foo:api:v1.0), but they specify it in completely different\nways that mean exactly the same thing. If you're using a library with\ngood namespace support to parse the document, this is hopefully made\ntransparent to you, otherwise you're going to have to struggle with the\nfact that in some cases the status code can be found in an element named\n\"foo:Status\" and in other cases it's in an element named just \"Status\".\n\nXML Selector is a bit opinionated about this. It assumes that most of the\ntime, you don't care about the namespace at all, you just want the Status\nelement. In the cases where you do care about the namespace, you don't\ncare whether the document author declared a namespace prefix or set the\ndefault namespace. You just want to access elements from the right one.\n\nUsing XML Selector you can access the `Code` attribute of the `Status`\nelement from both of the above documents either by not specifying a\nnamespace:\n\n```javascript\nq.find('Status').attr('Code');\n```\n\nor by explicitly ensuring you match elements with the correct namespace URI:\n\n```javascript\n$doc.addNamespace('acme', 'urn:acmecompany:foo:api:v1.0');\n$doc.find('acme:Status').attr('Code');\n```\n\n### Chaining Operations\n\nMost of the methods on XMLSelector return a new XMLSelector instance with\ntheir results. This allows you to chain together operations and easily\nbuild more complex searches from the basic ones provided by XML Selector.\nFor an example of how this is useful, let's consider this XML:\n\n```xml\n\u003ccatalog\u003e\n  \u003cbooks\u003e\n    \u003cbook\u003e\n      \u003ctitle\u003eBean Trees, The\u003c/title\u003e\n      \u003cauthor\u003eKingsolver, Barbara\u003c/author\u003e\n      \u003cpublished\u003e1988\u003c/published\u003e\n      \u003clanguages\u003e\u003cenglish/\u003e\u003c/languages\u003e\n      \u003cisbn-10\u003e0061097314\u003c/isbn-10\u003e\n      \u003cisbn-13\u003e978-0061097317\u003c/isbn-13\u003e\n      \u003cpublisher\u003eHarperTorch\u003c/publisher\u003e\n    \u003c/book\u003e\n    \u003cbook\u003e\n      \u003ctitle\u003eCien años de soledad\u003c/title\u003e\n      \u003cauthor\u003eGarcía Márquez, Gabriel\u003c/author\u003e\n      \u003cpublished\u003e1967\u003c/published\u003e\n      \u003clanguages\u003e\u003cspanish/\u003e\u003c/languages\u003e\n      \u003cisbn-10\u003e0307474720\u003c/isbn-10\u003e\n      \u003cisbn-13\u003e978-0307474728\u003c/isbn-13\u003e\n      \u003cpublisher\u003eVintage Espanol\u003c/publisher\u003e\n    \u003c/book\u003e\n    \u003cbook\u003e\n      \u003ctitle\u003eSan Manuel Bueno, mártir\u003c/title\u003e\n      \u003cauthor\u003ede Unamuno, Miguel\u003c/author\u003e\n      \u003cpublished\u003e1931\u003c/published\u003e\n      \u003clanguages\u003e\u003cspanish/\u003e\u003c/languages\u003e\n      \u003cisbn-10\u003e8437601851\u003c/isbn-10\u003e\n      \u003cisbn-13\u003e978-8437601854\u003c/isbn-13\u003e\n      \u003cpublisher\u003eCatedra\u003c/publisher\u003e\n    \u003c/book\u003e\n    \u003cbook\u003e\n      \u003ctitle\u003eTo Kill a Mockingbird\u003c/title\u003e\n      \u003cauthor\u003eLee, Harper\u003c/author\u003e\n      \u003cpublished\u003e1960\u003c/published\u003e\n      \u003clanguages\u003e\u003cenglish/\u003e\u003c/languages\u003e\n      \u003cisbn-10\u003e0446310786\u003c/isbn-10\u003e\n      \u003cisbn-13\u003e978-0446310789\u003c/isbn-13\u003e\n      \u003cpublisher\u003eGrand Central Publishing\u003c/publisher\u003e\n    \u003c/book\u003e\n  \u003c/books\u003e\n\u003c/catalog\u003e\n```\n\nNow let's say we'd like to list the titles of all the books in Spanish. We\ndon't have selectors sophisticated enough to match that pattern, but we can\ndo something like this:\n\n```javascript\n$doc.find('spanish').closest('book').find('title').map(function(t) { return $$(t).text(); });\n\n// produces: ['Cien años de soledad', 'San Manuel Bueno, mártir']\n```\n\n### Non-Matching Operations\n\nOne of the advantages we gain from building operations around sets is that\nwe don't have to introduce a lot of checks and special cases for\noperations that don't produce a match. Because the result of an operation\nthat doesn't match anything is an empty set, and performing operations on\nan empty set simply produces another empty set, a set of chained\noperations can remain very concise and still work correctly in the case of\nnon-matching operations.\n\nLet's say, for example, we want to find the titles of books in French instead:\n\n```javascript\n$doc.find('french').closest('book').find('title').map(function(t) { return $$(t).text(); });\n\n// produces: []\n```\n\nThis works as desired, even though we have three different operations that\nfollow a failed match. Again, that works because a non-match produces an\nempty set and not a value like `null`, `false`, or `undefined`.\n\n### Higher-Order Functions\n\nIt's possible to produce even more customized search operations by using\nsome of the higher-order functions which allow you to pass in callbacks\nfor filtering or finding elements. Continuing with the book example,\nlet's say we wanted the titles of the books by Unamuno:\n\n```javascript\n$doc.find('author')\n    .filter(function(elem) {\n      return /^de Unamuno,/.test($$(elem).text());\n    })\n    .closest('book')\n    .find('title')\n    .map(function(elem) {\n      return $$(elem).text();\n    });\n\n// produces: ['San Manuel Bueno, mártir']\n```\n\nUsing the same approach you could just as easily create a function to\nreturn the publication year for an ISBN:\n\n```javascript\nfunction isbnPubYear(isbn) {\n  return $doc.find(String(isbn).length == 10 ? 'isbn-10' : 'isbn-13')\n             .filter(function(elem) { return $$(elem).text() === isbn; })\n             .closest('book')\n             .find('published')\n             .text();\n}\n```\n\nThe functions `filter()` and `find()` both accept callbacks for this\npurpose, and several other functions allow you to iterate over, test, or\nmodify the set using callbacks. See the API section, below, for details.\n\n\u003ca name=\"section_api\"\u003e\u003c/a\u003e\n# API\n\n * [$$ (XML Selector)](#api_xml_selector)\n * [CharacterData](#api_character_data)\n * [Document](#api_document)\n * [Element](#api_element)\n * [Node](#api_node)\n\n\u003ca name=\"api_xml_selector\"\u003e\u003c/a\u003e\n## $$\n\nThis is the function exported by the `xml-selector` module. It may be\ninvoked directly to obtain a selector instance. It also provides a\nutility function for direct DOM usage.\n\n### [new] $$(xmlString)\n### [new] $$(node1[, ... nodeN])\n### [new] $$(nodeArray)\n\nAccepts an XML String, one or more nodes, an array of nodes, or any\ncombination thereof. It returns a new selector instance whose context is\nthe provided node list. It may be optionally be called with `new`, but\nthat is not required.\n\n### Instance Properties\n\n#### $selector.length\n\nThe number of nodes in this instance's list.\n\n### Instance Methods\n\n#### $selector[index]\n\n * `index`: **Number** Zero-based index\n\nInstances of a selector can be accessed by numerical index like an\narray, so you can do things like this:\n\n```javascript\nvar $$ = require('xml-selector');\n\nvar $doc = $$('\u003citems\u003e' +\n                '\u003citem content=\"Zero\" /\u003e' +\n                '\u003citem content=\"One\" /\u003e' +\n                '\u003citem content=\"Two\" /\u003e' +\n              '\u003c/items\u003e');\n\nvar $items = $doc.find('item');\n\nconsole.log($items[1].getAttribute('content'));\n// outputs 'One'\n```\n\nArray access returns a Node or `undefined`.\n\n#### $selector.addNamespace(prefix, uri)\n\n * `prefix`: **String** Namespace prefix to use in selector expressions\n * `uri`: **String** Corresponding namespace URI\n\nAssociates a prefix to use in your selectors with a namespace URI.\nReturns this selector instance.\n\n#### $selector.attr(name)\n\n * `name`: **String** Attribute name\n\nAccess the value of the named attribute from the first node in the list.\nReturns a String.\n\n#### $selector.children([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturn a new XML Selector instance containing the children of the nodes\nin this set, optionally filtered by `selector`.\n\n#### $selector.closest(selector)\n\n * `selector`: **String** Selector expression to match\n\nReturn a new XML Selector instance with the closest ancestor of each node\nin the list that matches `selector`.\n\n#### $selector.every(predicate[, thisArg])\n\n * `predicate`: **Function** Callback function for testing items, takes three arguments:\n   * `item`: **Node** The item to test\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nReturns `true` if all items in this set pass the given predicate (a\nuser-supplied callback which should return a boolean for each item\nsupplied).\n\n#### $selector.filter(selector)\n\n * `selector`: **String** Selector expression\n\nReturn a new XML Selector instance containing the nodes from this set\nthat match the given selector.\n\n#### $selector.filter(filterFunction[, thisArg])\n\n * `filterFunction`: **Function** Callback function for filtering items, takes three arguments:\n   * `item`: **Node** The item to test\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nReturn a new XML Selector instance containing only the nodes from this set for which the supplied callback returns `true`.\n\n#### $selector.find(selector)\n\n * `selector`: **String** Selector expression to search for\n\nAlias of `search`. Searches this set for descendants matching `selector`\nand returns a new XML Selector instance with the result.\n\n#### $selector.find(predicate[, thisArg])\n\n * `predicate`: **Function** Callback function for testing items, takes three arguments:\n   * `item`: **Node** The item to test\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nFind the first Node in this selector instance for which the user-supplied\ncallback returns `true`. Returns a Node or `undefined`.\n\n#### $selector.findIndex(predicate[, thisArg])\n\n * `predicate`: **Function** Callback function for testing items, takes three arguments:\n   * `item`: **Node** The item to test\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nIterate over the nodes in this selector instance and return the index of\nthe first node for which the user-supplied callback returns `true`.\nReturns the numerical index of the matching node, or -1 in the case of no\nmatch.\n\n#### $selector.first()\n\nReturns a new XML Selector instance containing the first node from this\nset.\n\n#### $selector.forEach(iterator[, thisArg])\n\n * `iterator`: **Function** Callback function, takes three arguments:\n   * `item`: **Node** The item\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nIterate over the nodes in this selector instance (behaves like\nArray.forEach). Returns this selector instance.\n\n#### $selector.last()\n\nReturns a new XML Selector instance containing the last node from this\nset.\n\n#### $selector.map(iterator[, thisArg])\n\n * `iterator`: **Function** Callback function, takes three arguments:\n   * `item`: **Node** The item to map\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nIterates over the nodes in this selector instance and returns a new Array\ncontaining the values returned by each invocation of `iterator`.\n\n#### $selector.next([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing the next siblings of the\nnodes in this set, optionally filtered by `selector`.\n\n#### $selector.nextAll([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing all the next siblings of\nthe nodes in this set, optionally filtered by `selector`.\n\n#### $selector.nextUntil(selector)\n\n * `selector`: **String** Selector expression\n\nReturns a new XML Selector instance containing all the next siblings of\nthe nodes in this set up to siblings matching `selector`.\n\n#### $selector.not(selector)\n\n * `selector`: **String** Selector expression\n\nReturns a new XML Selector instance containing the nodes in this set not\nmatching `selector`.\n\n#### $selector.parent([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing the parent of the nodes in\nthis set, optionally filtered by `selector`.\n\n#### $selector.parents([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing all the ancestors of the\nnodes in this set, optionally filtered by `selector`.\n\n#### $selector.parentsUntil(selector)\n\n * `selector`: **String** Selector expression\n\nReturns a new XML Selector instance containing all the ancestors of the\nnodes in this set up to the ancestor matching `selector`.\n\n#### $selector.prev([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing the previous siblings of\nthe nodes in this set, optionally filtered by `selector`\n\n#### $selector.prevAll([selector])\n\n * `selector`: **String** Optional selector expression\n\nReturns a new XML Selector instance containing all the previous siblings\nof the nodes in this set, optionally filtered by `selector`.\n\n#### $selector.prevUntil(selector)\n\n * `selector`: **String** Selector expression\n\nReturns a new XML Selector instance containing all the previous siblings\nof the nodes in this set up to siblings matching `selector`.\n\n#### $selector.reduce(iterator, initialValue[, thisArg])\n\n * `iterator`: **Function** Callback function, takes four arguments:\n   * `accumulator`: **Mixed** The value returned by the previous invocation of the callback\n   * `item`: **Node** The current item to process\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `initialValue`: **Mixed** Initial value for `accumulator`\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nCalls a function for each value in the collection (left-to-right) and\npasses the result to the next iteration. Returns the result of the final\ncall to `iterator`.\n\n#### $selector.reduceRight(iterator, initialValue[, thisArg])\n\n * `iterator`: **Function** Callback function, takes four arguments:\n   * `accumulator`: **Mixed** The value returned by the previous invocation of the callback\n   * `item`: **Node** The current item to process\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `initialValue`: **Mixed** Initial value for `accumulator`\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nCalls a function for each value in the collection (right-to-left) and\npasses the result to the next iteration. Returns the result of the final\ncall to `iterator`.\n\n#### $selector.search(selector)\n\n * `selector`: **String** Selector expression\n\nSearches this set for descendants matching `selector` and returns a new\nXML Selector instance with the result.\n\n#### $selector.some(predicate[, thisArg])\n\n * `predicate`: **Function** Callback function for testing items, takes three arguments:\n   * `item`: **Node** The item to test\n   * `index`: **Number** The index of the item in the list\n   * `$selector`: **XMLSelector** This selector instance\n * `thisArg`: **Mixed** Optional value to use as `this` when executing callback\n\nIterates over the Nodes in this selector instance and returns `true` if\n`predicate` returns `true` for at least one of the Nodes. Returns `false`\notherwise.\n\n#### $selector.text()\n\nReturns a String containing the text content of the first element in the\nlist. In the case of an empty set, an empty String is returned.\n\n#### $selector.xml()\n\nReturns a String containing the XML representation of the first element\nin the list. In the case of an empty set, an empty String is returned.\n\n### Utility Functions\n\n#### $$.parseFromString(xmlString)\n\n * `xmlString`: **String** A string of XML to parse\n\nParses a string of XML and returns a Document.\n\n\u003ca name=\"api_character_data\"\u003e\n## CharacterData\n\nCharacterData extends Node. It does not represent an actual node type,\nbut serves as the base class for Text and Comment node types. This\ninterface is defined in DOM Level 1. Currently a subset of that interface\nis implemented.\n\n### Instance Properties\n\n#### characterData.data\n\nA String containing the character data content of this Node.\n\n#### characterData.length\n\nA Number indicating the length of the `data` property.\n\n\u003ca name=\"api_document\"\u003e\n## Document\n\nDocument extends Node. It is the top-level node in a document tree. This\ninterface is defined in DOM Level 1. Currently a subset of that interface\nis implemented.\n\n### Instance Properties\n\n#### document.documentElement\n\nThe top-level Element from the document.\n\n\u003ca name=\"api_element\"\u003e\n## Element\n\nElement extends Node. It represents an XML element in the document. This\ninterface is defined in DOM Level 1. Currently a subset of that interface\nis implemented.\n\n### Instance Properties\n\n#### element.tagName\n\nA String containing the name of the element.\n\n### Instance Methods\n\n#### element.getAttribute(name)\n\n * `name`: **String** Attribute name\n\nReturn the value of the named attribute. Returns an empty string if the\nattribute is not set.\n\n\u003ca name=\"api_node\"\u003e\n## Node\n\nNode is the base type for all objects in the document tree. This\ninterface is defined in DOM Level 1. Currently a subset of that interface\nis implemented.\n\n### Instance Properties\n\n#### node.firstChild\n\nThe first child Node of this Node or `null` for none.\n\n#### node.lastChild\n\nThe last child Node of this Node or `null` for none.\n\n#### node.nextSibling\n\nThe sibling Node immediate following this Node in the document tree. This\nproperty is `null` in the case of no next sibling.\n\n#### node.nodeName\n\nA String containing the node name as defined in the DOM specification.\nFor Elements this is the same as the tag name. For other classes, the\nproperty value varies according to the node type.\n\n#### node.nodeType\n\nAn integer indicating the node type. Values follow the DOM specification:\n\n * 1 - **Element**\n * 2 - **Attr**\n * 3 - **Text**\n * 4 - **CDATASection**\n * 5 - **EntityReference**\n * 6 - **Entity**\n * 7 - **ProcessingInstruction**\n * 8 - **Comment**\n * 9 - **Document**\n * 10 - **DocumentType**\n * 11 - **DocumentFragment**\n * 12 - **Notation**\n\n#### node.ownerDocument\n\nThe Document that contains this Node. This property is `null` for the\nDocument itself.\n\n#### node.parentNode\n\nThe parent Node of this Node. If this Node has no parent, this property\nis `null`. The property will only be `null` for top-level nodes such as\nDocuments or DocumentFragments, attribute (Attr) nodes, or detached nodes.\n\n#### node.previousSibling\n\nThe sibling Node immediate preceding this Node in the document tree. This\nproperty is `null` in the case of no previous sibling.\n\n### Instance Methods\n\n#### node.hasChildNodes()\n\nReturns a boolean. Returns `true` if this node has children, `false` otherwise.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomcast%2Fxml-selector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomcast%2Fxml-selector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomcast%2Fxml-selector/lists"}