You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:35:23