我有一个XML文件,在处理它之前,我需要确保某个元素存在且不是空白。
这是我的代码:
CSV.open("#{csv_dir}/products.csv","w",{:force_quotes => true}) do |out|
out << headers
Dir.glob("#{xml_dir}/*.xml").each do |xml_file|
gdsn_doc = GDSNDoc.new(xml_file)
logger.info("Processing xml file #{xml_file}")
:x
@desc_exists = @gdsn_doc.xpath("//productData/description")
if !@desc_exists.empty?
row = []
headers.each do |col|
row << product[col]
end
out << row
end
end
end
以下代码无法找到“description”元素并检查它是否为空白:
@desc_exists = @gdsn_doc.xpath("//productData/description")
if !@desc_exists.empty?
以下是XML文件的示例:
<productData>
<description>Chocolate biscuits </description>
<productData>
这就是我定义班级和Nokogiri的方式:
class GDSNDoc
def initialize(xml_file)
@doc = File.open(xml_file) {|f| Nokogiri::XML(f)}
@doc.remove_namespaces!
代码必须移至早期阶段,Nokogiri已初始化。它不会产生运行时错误,但它确实允许带有空白描述的XML文件通过,而不应该。
class GDSNDoc
def initialize(xml_file)
@doc = File.open(xml_file) {|f| Nokogiri::XML(f)}
@doc.remove_namespaces!
desc_exists = @doc.xpath("//productData/descriptions")
if !desc_exists.empty?
答案 0 :(得分:0)
您正在创建这样的实例:
gdsn_doc = GDSNDoc.new(xml_file)
然后像这样使用它:
@desc_exists = @gdsn_doc.xpath("//productData/description")
@gdsn_doc
和gdsn_doc
是Ruby中的两个不同的东西 - 尝试使用不带@的版本:
@desc_exists = gdsn_doc.xpath("//productData/description")
答案 1 :(得分:0)
基本测试是使用:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<productData>
<description>Chocolate biscuits </description>
<productData>
EOT
# using XPath selectors...
doc.xpath('//productData/description').to_html # => "<description>Chocolate biscuits </description>"
doc.xpath('//description').to_html # => "<description>Chocolate biscuits </description>"
xpath
在正确解析文档时工作正常。
我收到错误“nil的未定义方法'xpath':NilClass(NoMethodError)
通常这意味着您没有正确解析文档。在你的情况下,这是因为你没有使用正确的变量:
gdsn_doc = GDSNDoc.new(xml_file)
...
@desc_exists = @gdsn_doc.xpath("//productData/description")
请注意,gdsn_doc
与@gdsn_doc
不同。后者似乎没有被初始化。
@doc = File.open(xml_file) {|f| Nokogiri::XML(f)}
虽然这应该有用,但将它写成:
是不恰当的@doc = Nokogiri::XML(File.read(xml_file))
如果您在块内处理并希望Ruby自动关闭文件,则首选{p> File.open(...) do ... end
。当您只是阅读然后将内容传递给其他内容进行处理时,这是不必要的,因此使用了File.read(...)
来篡改文件。 (Slurping不是一个好习惯,因为它可能存在可扩展性问题,但对于合理大小的XML / HTML,它是可以的,因为使用基于DOM的解析比SAX更容易。)
如果Nokogiri没有提出异常,则能够解析内容,但这并不意味着内容有效。检查
是个好主意@doc.errors
看看Nokogiri / libXML是否必须对内容进行一些修复才能解析它。修复标记可以根据您的预期更改DOM,从而无法根据您对选择器的假设查找标记。您可以使用xmllint
或其中一个XML验证程序进行检查,但Nokogiri仍然必须满意。
Nokogiri包含一个命令行版本nokogiri
,它接受您要解析的文档的URL:
nokogiri http://example.com
它将打开IRB,内容已加载并准备好你捅它。调试和测试时非常方便。如果您正在处理包含动态加载页面部分的DHTML的HTML,那么它也是确保内容实际存在的一种不错的方法。