新手问题 申手党:Nokogiri 如何搞定这个文本?

syutran · 2016年01月30日 · 最后由 fresh_fish 回复于 2016年02月14日 · 3525 次阅读

唉~从何说起呢? 万恶的谷歌服务器又宕机。向群里伸手只学了个开头,不得已啊只能来这申手。 按《提问的智慧》我在百度渡了一阵子,那形式啊走走也是走了啊,对不对? 然后,心安理得地来到这儿,开始发问:::::

我的文本是这个样子的:

<whcd>第一列</whcd><lxdh>第二列</lxdh><dwxs>第三列</dwxs> ...
<whcd>第一列</whcd><lxdh>第二列</lxdh><dwxs>第三列</dwxs> ...
<whcd>第一列</whcd><lxdh>第二列</lxdh><dwxs>第三列</dwxs> ...
<whcd>第一列</whcd><lxdh>第二列</lxdh><dwxs>第三列</dwxs> ...

我的目的是提取所有行部分列的值,我想用 file.each do |line| 逐行处理,感觉有点笨。 群里热心的大佬教我用 Nokogiri,我补习了一小时左右,根据一个例子(XML)搞了几下,卡着拉。

irb(main):001:0> require 'nokogiri'
=> true
irb(main):002:0> @doc = Nokogiri::XML(File.open("27065"))
=> #<Nokogiri::XML::Document:0x15619bc name="document" children=[#<Nokogiri::XML::Element:0x1561584 name="SBJGBH" children=[#<Nokogiri::XML::Text:0x15612a0 "37172713">]>]>
irb(main):003:0> @doc.xpath("/SBJGBH")
=> [#<Nokogiri::XML::Element:0x1561584 name="SBJGBH" children=[#<Nokogiri::XML::Text:0x15612a0 "37172713">]>]
irb(main):004:0> @doc.xpath("/ZGLB")
=> []
irb(main):005:0> 

只能 xpath 第一列的数据,搞不到第二列和其它列。 我估计是不是我的文件不是个 XML 文件的问题,还是哪儿用错了吗?

标题的“伸手党”和正文第一段文字完全没有意义,只会降低获得回答的可能性。

自从看了那个加了精的《XX 的智慧》,俺基本上很少发问了,不会就不会吧,反正只是个兴趣使然。有时候想想,哪个坛子里没几个白痴? 如果开头的那些话让人感到恶心,也许是我对那个《XX 的智慧》太敏感了吧,I'm sorry.

#2 楼 @syutran 不会就去 stackoverflow 问....真的

yes, thank you, I'm going now~

#3 楼 @cqcn1991 如果觉得这个问题太简单,应该去 stackoverflow 问,那么在 stackoverflow 上问这个问题的,不也是伸手党么?

#5 楼 @rubyfan1

  1. 如果问题问得不好,那你就会得到 downvote, 多搞几次就想明白应该怎么做了。总比一个人憋着强
  2. stackoverflow 对伸手党的容忍程度高多了。或者说,大家对伸手党的定义不一样。

#6 楼 @cqcn1991 第二点才是正解。

2012 年 11 月注册,论坛 ID 在 4000 左右,楼主你也是这个论坛的老兵了,对这个论坛的尿性应该很清楚了吧?

你给的数据样例和程序不匹配,让别人不好帮你,不过我猜只要

@doc.xpath("//ZGLB")

就可以了

楼主给个完整的数据样例比较好让别人帮助你解决。

1、到那个 stackoverflow 注册,还得开谷歌的服务器; 2、把这个傻问题提交后,一天得了 -3 分,而且没有任何回复; 3、趁谷歌的服务器没关机,找了几个例子,发现 .xpath("./name") 有戏,捣鼓到现在,算是把问题解决了,虽然方法更笨:

1、文档头尾加上<doc> </doc> 把整个文档圈起来;
2、同方法用<line></line>把每行圈起来;

require 'nokogiri'
# require 'ruby-pinyin'
doc = Nokogiri::XML(File.open("27065"),nil,"gbk")  # 27065是个文件名
nfile = File.new(File.join("./","output.txt"), "w+") #转换成新文件
print "doing" #在console里看进度,因为数据量大,有点动静就不是死机
i = 0
doc.xpath("//LINE").each do |l|
    i += 1
    # PinYin.of_string(l.xpath("./XM").text) #把汉字姓名转拼音 报错
    l.xpath("./XB").text == "1" ? xb = "M" : xb = "F" #原文中 男=1,女=2
    nfile.puts i.to_s.rjust(7,'0') + "|A|" + l.xpath("./SFZHM").text + "|" + xb + "|"  + l.xpath("./XM").text + "|" + " " + "|" + l.xpath("./TXDZ").text + "|" + l.xpath("./CSRQ").text + "|" + l.xpath("./YZBM").text + "|" + l.xpath("./SBKKH").text
    print "." #高大上的进度条
end
print "done" #进度条结束

1、只是没有把汉字转拼音搞定。 2、多谢各位大佬鼓励~,春节愉快!

社保局给我们银行的数据是这样子的: 而我们只需要其中的部分字段而且用“|”分割,才能导入到我们的系统。几万行数据,本来用 vi 能搞定,用 sed 和 awk 也能搞定,但我更想用 ruby 搞定,而且我还想用 rails 做成 web 搞定,以后用起来更方便。因为有百多家银行都要转换它。 唉,先慢慢来吧!

可以在 rails 中调用系统命令,命令里面用你说的 sed awk 搞定。这样你也可以在 rails 中变为 web 操作,只是 解析数据的操作用了 sed 和 awk 而已。

这个文本不如标题改为如何写这个Nokigiri.xpath

个人建议,如果列数不多的话花点时间替换成 csv 格式然后用 excel 打开感觉会更轻松点吧

这个用正则会不会简单点= =!

其实你看看 xpath 语法就明白了,http://www.w3school.com.cn/xpath/

需要 登录 后方可回复, 如果你还没有账号请 注册新账号