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
相关产品推荐
相关产品推荐

