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

VTD-XML含HTML <B>标签时调用vn.getText()返回-1问题咨询

解决VTD-XML中含子元素的元素调用getText()返回-1的问题

这个问题的核心原因是VTD-XML的getText()方法只返回当前元素的直接文本节点索引,而你的<string>元素里包含了<b>子元素,属于混合内容(文本+子元素),此时<string>本身没有直接的单一文本节点(它的子节点是文本节点、<b>元素、文本节点),所以getText()自然返回-1。

下面给出两种可行的解决方案:

方案1:使用XPath快速获取完整文本

最简洁的方式是用XPath的string(.)表达式,它会自动拼接当前元素下所有子节点的文本内容(包括子元素里的文本),无需手动遍历:

if (vnCurrent.toElement(VTDNav.FIRST_CHILD, "string")) {
    def xpath = new AutoPilot(vnCurrent)
    xpath.selectXPath("string(.)") // 选择当前元素的完整文本值
    
    while (true) {
        def currentStringValue = xpath.evalXPathToString()
        // 这里处理你的字符串值,比如输出"Sign in with %1$s"
        
        // 移动到下一个<string>元素
        if (!vnCurrent.toElement(VTDNav.NEXT_SIBLING, "string")) {
            break
        }
    }
}

方案2:手动遍历所有子节点收集文本

如果你需要更精细的控制(比如保留标签信息,或者区分不同子节点的文本),可以手动遍历当前元素的所有子节点,逐个提取文本:

if (vnCurrent.toElement(VTDNav.FIRST_CHILD, "string")) {
    while (true) {
        def fullText = new StringBuilder()
        int childIndex = vnCurrent.getFirstChild()
        
        // 遍历<string>的所有子节点
        while (childIndex != -1) {
            int tokenType = vnCurrent.getTokenType(childIndex)
            
            // 处理文本节点
            if (tokenType == VTDNav.TOKEN_CHARACTER_DATA || tokenType == VTDNav.TOKEN_CDATA) {
                fullText.append(vnCurrent.toRawString(childIndex))
            } 
            // 处理子元素(比如<b>),提取它的文本
            else if (tokenType == VTDNav.TOKEN_STARTING_TAG) {
                int innerChild = vnCurrent.getFirstChild(childIndex)
                while (innerChild != -1) {
                    if (vnCurrent.getTokenType(innerChild) == VTDNav.TOKEN_CHARACTER_DATA) {
                        fullText.append(vnCurrent.toRawString(innerChild))
                    }
                    innerChild = vnCurrent.getNextSibling(innerChild)
                }
            }
            
            childIndex = vnCurrent.getNextSibling(childIndex)
        }
        
        def currentStringValue = fullText.toString()
        // 处理获取到的完整文本
        
        if (!vnCurrent.toElement(VTDNav.NEXT_SIBLING, "string")) {
            break
        }
    }
}

补充说明

  • getText()的设计逻辑是:仅当当前元素的直接子节点是单一文本节点时,才返回该文本节点的索引;如果有子元素或者多个文本节点,就会返回-1。
  • 方案1的XPath方式更适合大多数场景,代码简洁且不易出错;方案2适合需要自定义处理子元素的场景。

内容的提问来源于stack exchange,提问作者kenyee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:08:19