使用Nokogiri解析Yandex地理编码XML文档失败求助
解决Nokogiri解析带命名空间XML的问题
这个问题我之前碰到过,根源在于你的XML文档包含默认命名空间(xmlns="http://maps.yandex.ru/1.x"),Nokogiri在处理这类XML时,不会自动将无前缀的XPath节点映射到默认命名空间,导致直接用//lowerCorner查询不到目标节点。
具体修复方案
方法1:动态获取命名空间并绑定前缀
这种方法更灵活,不需要硬编码固定的命名空间地址:
# 原请求代码保持不变 response = Nokogiri::XML(open('https://geocode-maps.yandex.ru/1.x/?geocode=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3+%D0%A1%D0%B2%D0%B5%D1%80%D0%B4%D0%BB%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F+%D0%BD%D0%B0%D0%B1%D0%B5%D1%80%D0%B5%D0%B6%D0%BD%D0%B0%D1%8F+44%D0%A2'), nil, Encoding::UTF_8.to_s) # 获取根节点的默认命名空间地址 default_namespace = response.root.namespace.href # 绑定命名空间前缀后查询节点 lowerCorner = response.xpath("//xmlns:lowerCorner", xmlns: default_namespace) # 验证并输出结果 puts lowerCorner.text if lowerCorner.any?
方法2:直接硬编码命名空间前缀
如果你确认该XML的命名空间地址不会变化,可以直接绑定自定义前缀查询:
response = Nokogiri::XML(open('https://geocode-maps.yandex.ru/1.x/?geocode=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3+%D0%A1%D0%B2%D0%B5%D1%80%D0%B4%D0%BB%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F+%D0%BD%D0%B0%D0%B1%D0%B5%D1%80%D0%B5%D0%B6%D0%BD%D0%B0%D1%8F+44%D0%A2'), nil, Encoding::UTF_8.to_s) # 绑定命名空间前缀(这里用y作为前缀,可自定义) lowerCorner = response.xpath("//y:lowerCorner", y: "http://maps.yandex.ru/1.x") # 输出节点内容 puts lowerCorner.text if lowerCorner.present?
额外注意事项
- 可以先通过
puts response.to_s打印完整XML,确认返回的文档中确实存在lowerCorner节点。 - 你已经指定了
Encoding::UTF_8.to_s,这部分编码处理是正确的,避免了乱码问题。
内容的提问来源于stack exchange,提问作者Alexander Gorg




