Use xpath in javascript

Use xpath in javascript

Last updated: Jan 12, 2023
Reading time · 2 min

banner

# Get Element by XPath using JavaScript — Examples

Use the document.evaluate() method to get an element by XPath. The method returns an XPathResult based on the provided XPath expression and the supplied parameters.

Here is the HTML for the examples.

Copied!
DOCTYPE html> html lang="en"> head> meta charset="UTF-8" /> title>bobbyhadz.comtitle> head> body> div> p>Hello worldp> div> div> p>Apple, Banana, Kiwip> div> script src="index.js"> script> body> html>

And here is the related JavaScript.

Copied!
// ✅ Get specific `p` element const firstP = document.evaluate( '/html/body/div[2]/p', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null, ).singleNodeValue; console.log(firstP); // 👉️ p console.log(firstP.textContent); // 👉️ "Apple, Banana, Kiwi" // ----------------------- // ✅ Get all P elements const allParagraphs = document.evaluate( '/html/body//p', document, null, XPathResult.ANY_TYPE, null, ); console.log(allParagraphs); let currentParagraph = allParagraphs.iterateNext(); while (currentParagraph) console.log(currentParagraph.textContent); currentParagraph = allParagraphs.iterateNext(); >

We used the document.evaluate method to get an XPathResult based on an XPath expression.

The first example shows how to get a single node, whereas the second gets a collection of nodes and iterates over it.

The document.evaluate method takes the following parameters:

  1. xpathExpression — the XPath to be evaluated
  2. contextNode — the context node for the query (usually document)
  3. namespaceResolver — should be null when working with HTML documents
  4. resultType — the type of XPathResult to return.
  5. result — should be null

Notice that in the first example, we accessed the singleNodeValue property on the XPathResult object.

Copied!
// ✅ Get specific `p` element const firstP = document.evaluate( '/html/body/div[2]/p', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null, ).singleNodeValue; console.log(firstP); // 👉️ p console.log(firstP.textContent); // 👉️ "Apple, Banana, Kiwi"

This will evaluate to null if the node set is empty.

Another thing to note in the example is that we specified a result type of XPathResult.FIRST_ORDERED_NODE_TYPE .

If you look at the XPath Result types table, this result type returns any single node that matches the provided XPath expression.

In the second example, we used an XPath expression to get all p elements in the document and iterated over the results.

Copied!
// ✅ Get all P elements const allParagraphs = document.evaluate( '/html/body//p', document, null, XPathResult.ANY_TYPE, null, ); let currentParagraph = allParagraphs.iterateNext(); while (currentParagraph) // 👇️ "Hello world", "Apple, Banana, Kiwi" console.log(currentParagraph.textContent); currentParagraph = allParagraphs.iterateNext(); >

This time we set XPAthResult.ANY_TYPE as the result type, which returns whatever type results from the provided XPath expression.

The returned XPathResult object is a Node-set of matches nodes that behave as an iterator.

We are able to access the individual nodes by using the iterateNext() method of the XPathResult object.

Once we have iterated over all of the nodes, the iterateNext() method will return null .

Note that modifying a node will invalidate the iterator. After modifying a node, attempting to iterate over the results generates an error.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

Введение в использование XPath в JavaScript

В этом документе описывается интерфейс для использования XPath в JavaScript внутри, в расширениях и на веб-сайтах. Mozilla реализует изрядное количество DOM 3 XPath , что означает, что выражения XPath можно запускать как для HTML, так и для XML-документов.

Основным интерфейсом использования XPath является функция оценки объекта документа .

document.evaluate()

Этот метод оценивает выражения XPath для документа на основе XML (включая документы HTML) и возвращает объект XPathResult , который может быть отдельным узлом или набором узлов. Существующая документация по этому методу находится по адресу document.evaluate , но на данный момент она довольно скудна для наших нужд; более подробное рассмотрение будет дано ниже.

const xpathResult = document.evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result);

Parameters

Метод Assessment evaluate() принимает в общей сложности пять параметров:

  • xpathExpression : строка, содержащая выражение XPath для оценки.
  • contextNode : узел в документе, по которому должно оцениваться xpathExpression , включая все его дочерние узлы. Узел документа является наиболее часто используемым.
  • namespaceResolver : функция, которая будет передавать любые префиксы пространства имен, содержащиеся в xpathExpression , которая возвращает строку, представляющую URI пространства имен, связанный с этим префиксом. Это позволяет преобразовывать префиксы, используемые в выражениях XPath, и, возможно, разные префиксы, используемые в документе. Функция может быть либо:
    • Создано с помощью createNSResolver метода XPathEvaluator объекта. Вы должны использовать это практически все время.
    • null , который можно использовать для документов HTML или когда не используются префиксы пространства имен. Обратите внимание: если xpathExpression содержит префикс пространства имен, это приведет к возникновению исключения DOMException с кодом NAMESPACE_ERR .
    • Пользовательская определяемая пользователем функция. Дополнительные сведения см. в разделе «Использование определяемого пользователем преобразователя пространства имен» в приложении.

    Return Value

    Возвращает xpathResult , который является объектом XPathResult типа, указанного в параметре resultType . XPathResult интерфейса определяется здесь .

    Реализация резольвера пространства имен по умолчанию

    Мы создаем преобразователь пространства имен, используя метод createNSResolver объекта документа .

    const nsResolver = document.createNSResolver(contextNode.ownerDocument === null ? contextNode.documentElement : contextNode.ownerDocument.documentElement);

    Или же с помощью createNSResolver метода XPathEvaluator объекта.

    const xpEvaluator = new XPathEvaluator(); const nsResolver = xpEvaluator.createNSResolver(contextNode.ownerDocument === null ? contextNode.documentElement : contextNode.ownerDocument.documentElement);

    Затем передайте document.evaluate , переменную nsResolver , в качестве параметра namespaceResolver .

    Примечание: XPath определяет QName без префикса, чтобы соответствовать только элементам в нулевом пространстве имен. В XPath нет способа выбрать пространство имен по умолчанию применительно к обычной ссылке на элемент (например, p[@id=’_myid’] для xmlns=’http://www.w3.org/1999/xhtml’ ) . Чтобы сопоставить элементы по умолчанию в непустом пространстве имен, вам нужно либо обратиться к конкретному элементу, используя форму, такую ​​как [‘namespace-uri()=’http://www.w3.org/1999/xhtml’ and name()=’p’ and @id=’_myid’] ( этот подход хорошо работает для динамических XPath, где пространства имен могут быть неизвестны) или используйте тесты префиксных имен и создайте преобразователь пространства имен, сопоставляющий префикс с пространством имен. Узнайте больше о том , как создать определяемый пользователем преобразователь пространства имен., если вы хотите использовать последний подход.

    Notes

    Адаптирует любой узел DOM для разрешения пространств имен, чтобы выражение XPath можно было легко вычислить относительно контекста узла, в котором оно появилось в документе. Этот адаптер работает аналогично методу DOM уровня 3 lookupNamespaceURI на узлах при разрешении namespaceURI из заданного префикса с использованием текущей информации, доступной в иерархии узла во время lookupNamespaceURI . Также правильно разрешает неявный префикс xml .

    Указание типа возврата

    Возвращаемая переменная xpathResult из document.evaluate может состоять либо из отдельных узлов ( простые типы ), либо из коллекции узлов ( типы с набором узлов ).

    Simple Types

    Когда желаемый тип результата в resultType указан как:

    Мы получаем возвращаемое значение выражения, обращаясь соответственно к следующим свойствам объекта XPathResult .

    Example

    Следующее использует выражение XPath count(//p) для получения количества элементов

    в документе HTML:

    const paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null); console.log(`This document contains $ paragraph elements.`);

    Хотя JavaScript позволяет нам преобразовывать число в строку для отображения, интерфейс XPath не будет автоматически преобразовывать числовой результат, если stringValue свойство stringValue , поэтому следующий код не будет работать:

    const paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null); console.log(`This document contains $ paragraph elements.`);

    Вместо этого он вернет исключение с кодом NS_DOM_TYPE_ERROR .

    Node-Set Types

    Объект XPathResult позволяет возвращать наборы узлов трех разных типов:

    Iterators

    Когда указанный тип результата в параметре resultType :

    XPathResult объект , возвращаемый является узлом-набор соответствующих узлов , которые будут вести себя в качестве итератора, что позволяет нам получить доступ к отдельным узлам , содержащихся с помощью iterateNext() метод XPathResult .

    После того, как мы перебрали все отдельные согласованные узлы, iterateNext() вернет null .

    Однако следует отметить, что если документ мутирует (дерево документа изменяется) между итерациями , которые будут недействительной итерацию и invalidIteratorState свойства XPathResult устанавливается в true , и NS_ERROR_DOM_INVALID_STATE_ERR исключении.

    const iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); try < let thisNode = iterator.iterateNext(); while (thisNode) < console.log(thisNode.textContent); thisNode = iterator.iterateNext(); > > catch(e) < console.error(`Error: Document tree modified during iteration $ `); >
    Snapshots

    Когда указанный тип результата в параметре resultType :

    XPathResult объект , возвращаемый представляет собой статический набор узлов совпадающих узлов, что позволяет получить доступ к каждому узлу через snapshotItem(itemNumber) способа по XPathResult объекта, где itemNumber является индекс узла должны быть извлечены. К общему количеству содержащихся узлов можно получить доступ через свойство snapshotLength .

    Снимки не изменяются при мутациях документа,поэтому,в отличие от итераторов,снимок не становится недействительным,но он может не соответствовать текущему документу,например,узлы могли быть перемещены,он может содержать узлы,которые больше не существуют,или могли быть добавлены новые узлы.

    const nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (let i=0; i < nodesSnapshot.snapshotLength; i++) < console.log(nodesSnapshot.snapshotItem(i).textContent); >
    First Node

    Когда указанный тип результата в параметре resultType :

    XPathResult объект возвращен только первый узел обнаружил , что соответствует выражению XPath. Это может быть доступно через singleNodeValue свойства XPathResult объекта. Это будет null , если набор узлов пуст.

    Обратите внимание,что для неупорядоченного подтипа единственный возвращаемый узел может быть не первым в порядке документов,но для упорядоченного подтипа вы гарантированно получите первый совпадающий узел в порядке документов.

    const firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); console.log(`The first phone number found is $ `);

    Константа ANY_TYPE

    Когда тип результата в параметре resultType указан как ANY_TYPE , XPathResult объект XPathResult будет любого типа, который естественным образом является результатом вычисления выражения.

    Это может быть любой из простых типов ( тип NUMBER_TYPE, STRING_TYPE, BOOLEAN_TYPE ), но , если возвращенный тип результатом является набор узлов , то это будет только быть UNORDERED_NODE_ITERATOR_TYPE .

    Чтобы определить этот тип после оценки, мы используем свойство resultType объекта XPathResult . Постоянные значения этого свойства определены в приложении. Пока нет =====Any_Type Example=====

    Источник

    Читайте также:  Html код колесо фортуны
Оцените статью