如何用Ruby/Nokogiri从嵌套XML中提取指定元素值?
解决Nokogiri提取XML元素值的问题
我帮你分析下问题所在:你当前代码里用的//EE这种XPath是绝对路径,它会匹配整个XML文档里所有的<EE>元素,然后把它们的文本直接拼接在一起,这就是为什么你得到3Z94PL而不是分开的3Z9和4PL。同理,//PR也会把所有PR的文本拼起来,导致输出不符合预期。
下面是修正后的代码,能实现你想要的效果:
require 'nokogiri' xml = <<_ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <main> <Oganin> <Oganna>EJ-MKKL</Oganna> <CutryI>YUFG</CutryI> <Ntwl> <Ntrk> <TGCo>KOLPWE</TGCo> <NtrkType>Uymmls</NtrkType> <NtrkData> <Rutins> <Rutinf> <CTT> <GT_Nmbbrs> <RngeDat> <Nmbbr> <EE>3Z9</EE> <PR>45</PR> </Nmbbr> </RngeDat> <RngeDat> <Nmbbr> <EE>4PL</EE> <PR>156</PR> <Srng> <Brng>73359</Brng> <Erng>86353</Erng> </Srng> </Nmbbr> </RngeDat> </GT_Nmbbrs> </CTT> </Rutinf> </Rutins> </NtrkData> </Ntrk> </Ntwl> </Oganin> </main> _ doc = Nokogiri.XML(xml) values = [] # 遍历每个RngeDat节点,逐个处理里面的元素 doc.xpath("//NtrkData/Rutins//GT_Nmbbrs/RngeDat").each do |rnge_dat| # 用.//开头的XPath,只查找当前RngeDat节点下的子元素 values << rnge_dat.xpath(".//EE").text values << rnge_dat.xpath(".//PR").text # 检查Brng和Erng是否存在,存在才加入结果 brng_text = rnge_dat.xpath(".//Brng").text values << brng_text unless brng_text.empty? erng_text = rnge_dat.xpath(".//Erng").text values << erng_text unless erng_text.empty? end # 把所有收集到的值用空格连接输出 puts values.join(' ')
关键修正点:
- 用
each遍历每个<RngeDat>节点,确保我们处理的是单个节点下的子元素,而不是整个文档的所有匹配元素。 - XPath路径改为
.//EE(注意开头的.),这个.表示当前节点,只会在当前<RngeDat>下查找对应的元素,不会跨节点匹配。 - 把所有提取到的值存入数组,最后用
join(' ')拼接成空格分隔的字符串,完美符合你的期望输出。
运行这段代码后,输出就是:
3Z9 45 4PL 156 73359 86353
内容的提问来源于stack exchange,提问作者Ger Cas
相关产品推荐
相关产品推荐

