Ruby 如何使用Nokogiri读卡器界面告知节点的行号?

Ruby 如何使用Nokogiri读卡器界面告知节点的行号?,ruby,xml,nokogiri,Ruby,Xml,Nokogiri,我正在尝试编写一个Nokogiri脚本,该脚本将grep XML用于包含ASCII双引号(«“»)的文本节点。由于我想要类似grep的输出,我需要行号和每行的内容。但是,我看不到如何告诉行号元素的起始位置。下面是我的代码: require 'rubygems' require 'nokogiri' ARGV.each do |filename| xml_stream = File.open(filename) reader = Nokogiri::XML::Reader(xml

我正在尝试编写一个Nokogiri脚本,该脚本将grep XML用于包含ASCII双引号(«“»)的文本节点。由于我想要类似grep的输出,我需要行号和每行的内容。但是,我看不到如何告诉行号元素的起始位置。下面是我的代码:

require 'rubygems'
require 'nokogiri'

ARGV.each do |filename|
    xml_stream = File.open(filename)
    reader = Nokogiri::XML::Reader(xml_stream)
    titles = []
    text = ''
    grab_text = false
    reader.each do |elem|
        if elem.node_type == Nokogiri::XML::Node::TEXT_NODE
            data = elem.value
            lines = data.split(/\n/, -1);

            lines.each_with_index do |line, idx|
                if (line =~ /"/) then
                    STDOUT.printf "%s:%d:%s\n", filename, elem.line()+idx, line
                end
            end
        end
    end
end

elem.line()不起作用。

XML和解析器实际上没有行号的概念。您指的是文件的物理布局

您可以使用访问器使用解析器玩一个游戏,查找包含换行符和/或回车符的文本节点,但由于XML允许嵌套节点,因此可能会被丢弃

require 'nokogiri'

xml =<<EOT_XML
<atag>
  <btag>
    <ctag 
      id="another_node">
      other text
    </ctag>
  </btag>
  <btag>
    <ctag id="another_node2">yet
                             another
                             text</ctag>
    </btag>
  <btag>
    <ctag id="this_node">this text</ctag>
  </btag>
</atag>
EOT_XML

doc = Nokogiri::XML(xml)

# find a particular node via CSS accessor
doc.at('ctag#this_node').text # => "this text"

# count how many "lines" there are in the document
doc.search('*/text()').select{ |t| t.text[/[\r\n]/] }.size # => 12

# walk the nodes looking for a particular string, counting lines as you go
content_at = []
doc.search('*/text()').each do |n|
  content_at << [n.line, n.text] if (n.text['this text'])
end
content_at # => [[14, "this text"]]
需要“nokogiri”
xml=12
#遍历节点寻找特定字符串,边走边数行
content_at=[]
doc.search('*/text()')。每个都做| n|
内容在[[14,“本文本”]]
这是因为解析器能够找出什么是文本节点并干净地返回它,而不依赖正则表达式或文本匹配



编辑:我浏览了一些旧代码,在Nokogiri的文档中搜索了一些,并得出了上面编辑过的更改。它工作正常,包括处理一些病理病例。Nokogiri FTW!

嗯,我正在尝试输出一些类似grep-n的输出,我可以轻松地输入到Vim中。顺便说一句,我还尝试了一个CPAN的XML解析器xt,能够告诉我文件文本中文本节点开始的物理行,这样我就可以使用拆分计算双引号的出现。这最终奏效了。所以我对你的答案有点不满意,并假设这是Nokogiri的缺陷。如果你不喜欢某个答案,你不应该接受它。Nokogiri使用libXML2作为答案s engine是一个行业标准的解析器,所以我几乎不认为Nokogiri有什么错。我已经多年没有使用Perl的XML解析器了。它可能使用Expat,这是一个较旧的解析器,也可能使用libXML2,或者它可以用Perl来完成所有的工作。但是它在做这些工作时,仍然会遇到同样的问题,并且可能会出现同样的错误way.@Shlomi Fish,看看编辑过的代码。它很简洁,处理了我认为会抛弃Nokogiri的条件。几年前,我从Hpricot XML解析器切换到专门使用Nokogiri,这再次向我展示了它有多好。