Kotlin多平台JS中Document.evaluate()引用未解决问题求助
Kotlin多平台JS中使用Document.evaluate()的问题解决
在Kotlin多平台JavaScript环境中调用Document.evaluate()时出现Unresolved reference: evaluate和Unresolved reference: XPathResult错误,核心原因是Kotlin的W3C DOM标准绑定默认未包含XPath相关的扩展API,以下是两种可行的解决方式:
方法一:类型安全的接口声明(推荐)
手动声明缺失的XPath相关接口和Document扩展方法,让Kotlin识别这些原生JS API:
import org.w3c.dom.Document import org.w3c.dom.Node import org.w3c.dom.parsing.DOMParser // 声明XPathResult接口,对应浏览器原生的XPathResult对象 external interface XPathResult { val snapshotLength: Int fun snapshotItem(index: Int): Node? companion object { // 按需添加需要的结果类型常量 val ORDERED_NODE_SNAPSHOT_TYPE: Short val UNORDERED_NODE_ITERATOR_TYPE: Short } } // 给Document扩展evaluate方法,匹配原生JS的签名 external fun Document.evaluate( xpathExpression: String, contextNode: Node, namespaceResolver: ((String) -> String?)?, resultType: Short, result: XPathResult? ): XPathResult object JavascriptTest { // language=HTML private val html = """ <body> <div> <a class="button" href="http://exaple.com">Example</a> </div> </body> """.trimIndent() fun parseXpath() { val parser = DOMParser() val document: Document = parser.parseFromString(html, "text/html") val xpath = "//div/a[contains(@class, \"button\")]" // 现在可以正常调用evaluate方法 val result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) // 示例:获取匹配的节点并打印href for (i in 0 until result.snapshotLength) { val link = result.snapshotItem(i) as? org.w3c.dom.HTMLAnchorElement println(link?.href) } } }
说明
- 使用
external关键字告诉Kotlin这是原生JS中存在的接口/方法,无需在Kotlin中实现 - 可以根据业务需求补充XPathResult的其他属性或方法(比如迭代器相关方法)
方法二:动态类型(快速测试用)
如果不需要严格的类型检查,可将Document转为dynamic类型直接调用原生API:
import org.w3c.dom.Document import org.w3c.dom.parsing.DOMParser object JavascriptTest { // language=HTML private val html = """ <body> <div> <a class="button" href="http://exaple.com">Example</a> </div> </body> """.trimIndent() fun parseXpath() { val parser = DOMParser() val document: Document = parser.parseFromString(html, "text/html") val xpath = "//div/a[contains(@class, \"button\")]" // 转为dynamic绕过类型检查 val dynamicDoc = document as dynamic val xpathResult = js("XPathResult") val result = dynamicDoc.evaluate(xpath, document, null, xpathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) // 处理结果 println(result.snapshotLength) val link = result.snapshotItem(0) as? org.w3c.dom.HTMLAnchorElement println(link?.href) } }
说明
- 这种方式无需声明接口,但会失去Kotlin的类型安全特性,适合快速验证逻辑
Build配置注意
你的build.gradle.kts配置无需额外修改,当前的JS IR + CommonJS配置已经可以支持这些原生API调用,只要代码中正确声明或动态调用即可。
内容的提问来源于stack exchange,提问作者vovahost
相关产品推荐
相关产品推荐

