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

OpenRefine中基于XML元素值提取属性值的问题求助

OpenRefine处理Nominatim XML数据:提取指定城市的lat属性

一、GREL替代方案(推荐)

OpenRefine原生的GREL语法可直接处理XML,无需编写Jython脚本,彻底避开编码问题,操作更高效。

核心表达式

forEach(xml(value).select("//place[city='Paris']"), node, node.attr("lat")).join("; ")

表达式说明

  • xml(value):将单元格文本转换为可操作的XML对象
  • select("//place[city='Paris']"):用XPath筛选所有包含<city>Paris</city>子元素的<place>节点(请根据你的实际XML结构替换place为对应父节点名)
  • forEach(..., node, node.attr("lat")):遍历筛选出的节点,提取每个节点的lat属性值
  • join("; "):若有多个匹配结果,用分号分隔;仅需第一个匹配值时,可改为xml(value).select("//place[city='Paris']")[0].attr("lat")

二、Jython编码问题修复方案

如果坚持使用Jython,需确保全程处理Unicode字符串,避免字节串与字符串混用引发编码错误。

修正后的代码

from xml.etree import ElementTree as ET

# 统一转换为Unicode字符串,解决编码冲突
xml_content = unicode(value, 'utf-8') if isinstance(value, str) else value

try:
    root = ET.fromstring(xml_content)
    # 替换为你XML中实际的父节点名称(示例为place)
    target_nodes = root.findall(".//place")
    result_lats = []
    
    for node in target_nodes:
        city_node = node.find("city")
        # 检查city元素存在且文本匹配
        if city_node is not None and city_node.text and city_node.text.strip() == 'Paris':
            lat_val = node.get("lat")
            if lat_val:
                result_lats.append(lat_val)
    
    return "; ".join(result_lats) if result_lats else None
except Exception as e:
    return str(e)

关键修复点

  • 先将单元格值统一转为Unicode字符串,避免OpenRefine中字节串与字符串的编码冲突
  • 移除不必要的.encode('utf8')调用,ET.fromstring接受Unicode字符串作为输入
  • 增加空值判断(如city_node.text是否存在),避免因XML节点缺失导致的报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:20:20