Попытка решить, что более подходит для моего случая использования …
После сравнения документации по этим методам мое смутное понимание evaluate
возвращает типизированный результат, но query
этого не делает. Кроме того, пример query
включает в себя цикл через множество результатов, но пример evaluate
предполагает один типизированный результат.
Все еще не намного мудрее! Может ли кто-нибудь объяснить (как можно ближе к терминам непрофессионала), когда вы будете использовать тот или иной, – например, будут ли упомянутые выше множественные / одиночные результаты?
DOMXPath :: query () поддерживает только выражения, которые возвращают список узлов. DOMXPath :: evaluation () поддерживает все допустимые выражения. Официальный метод также называется методом оценки (): http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
Выберите все элементы p
внутри div
: //div//p
Выберите все атрибуты href
в элементах текущего документа: //a/@href
Вы можете использовать функцию string()
чтобы передать первый элемент списка узлов в строку. Это не будет работать с DOMXpath :: query ().
Выберите текст заголовка документа: string(/html/head/title)
Существуют другие функции и операторы, которые изменят тип результата выражения. Но это всегда однозначно. Вы всегда будете знать, какой тип результата.
query
вернет DOMNodeList
независимо от вашего фактического выражения XPath. Это говорит о том, что вы не знаете, каким может быть результат. Таким образом, вы можете перебирать список и проверять тип узлов узлов и делать что-то на основе этого типа.
Но query
не ограничивается этим вариантом использования. Вы все еще можете использовать это, когда знаете, какой тип вы получите. В будущем может быть более читаемым то, чего вы хотели достичь, и поэтому его легче поддерживать.
evaluate
с другой стороны, дает вам именно тот тип, который вы выберете. Как показывают примеры:
$xpath->evaluate("1 = 0"); // FALSE $xpath->evaluate("string(1 = 0)"); // "false"
Как оказалось, выбирая атрибуты //div/@id
или текстовые узлы //div/text()
прежнему DOMNodeList
вместо строк. Поэтому потенциальные варианты использования ограничены. Вы должны были бы заключить их в string
: string(//div/@id)
или string(//div/text())
текстовых узлов string(//div/text())
.
Главное преимущество evaluate
заключается в том, что вы можете получить строки из вашего DOMDocument
с меньшим количеством строк кода. В противном случае он будет выдавать тот же результат, что и query
.
Ответ ThW прав, что некоторые выражения не будут работать с query
:
$xpath->query("string(//div/@id)") // DOMNodeList of length 0 $xpath->evaluate("string(//div/@id)") // string with the found id