Попытка решить, что более подходит для моего случая использования …
После сравнения документации по этим методам мое смутное понимание 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