我试图解析的XML文件包含属性中包含的所有数据。我找到了如何构建要插入文本文件的字符串。
我有这个XML文件:
<ig:prescribed_item class_ref="0161-1#01-765557#1">
<ig:prescribed_property property_ref="0161-1#02-016058#1" is_required="false" combination_allowed="false" one_of_allowed="false">
<dt:measure_number_type representation_ref="0161-1#04-000005#1">
<dt:real_type>
<dt:real_format pattern="\d(1,)\.\d(1,)"/>
</dt:real_type>
<dt:prescribed_unit_of_measure UOM_ref="0161-1#05-003260#1"/>
</dt:measure_number_type>
</ig:prescribed_property>
<ig:prescribed_property property_ref="0161-1#02-016059#1" is_required="false" combination_allowed="false" one_of_allowed="false">
<dt:measure_number_type representation_ref="0161-1#04-000005#1">
<dt:real_type>
<dt:real_format pattern="\d(1,)\.\d(1,)"/>
</dt:real_type>
<dt:prescribed_unit_of_measure UOM_ref="0161-1#05-003260#1"/>
</dt:measure_number_type>
</ig:prescribed_property>
</ig:prescribed_item>
</ig:identification_guide>
我想将它解析成这样的文本文件,并为每个属性复制类ref:
class_ref|property_ref|is_required|UOM_ref
0161-1#01-765557#1|0161-1#02-016058#1|false|0161-1#05-003260#1
0161-1#01-765557#1|0161-1#02-016059#1|false|0161-1#05-003260#1
这是我到目前为止的代码:
require 'nokogiri'
doc = Nokogiri::XML(File.open("file.xml"), 'UTF-8') do |config|
config.strict
end
content = doc.xpath("//ig:prescribed_item/@class_ref").map {|i|
i.search("//ig:prescribed_item/ig:prescribed_property/@property_ref").map { |d| d.text }
}
puts content.inspect
content.each do |c|
puts c.join('|')
end
答案 0 :(得分:0)
肯定有基于属性解析的方法。
发动机场文章“Getting started with Nokogiri”有完整的描述。
但很快,他们给出的例子是:
匹配具有类的“h3”标签 属性,我们写道:
h3[@class]
匹配其类的“h3”标签 attribute等于字符串“r”, 我们写道:
h3[@class = "r"]
使用属性匹配 构造,我们可以修改我们以前的 查询:
//h3[@class = "r"]/a[@class = "l"]
答案 1 :(得分:0)
我使用CSS访问器简化了一下:
xml = <<EOT
<ig:prescribed_item class_ref="0161-1#01-765557#1">
<ig:prescribed_property property_ref="0161-1#02-016058#1" is_required="false" combination_allowed="false" one_of_allowed="false">
<dt:measure_number_type representation_ref="0161-1#04-000005#1">
<dt:real_type>
<dt:real_format pattern="\d(1,)\.\d(1,)"/>
</dt:real_type>
<dt:prescribed_unit_of_measure UOM_ref="0161-1#05-003260#1"/>
</dt:measure_number_type>
</ig:prescribed_property>
<ig:prescribed_property property_ref="0161-1#02-016059#1" is_required="false" combination_allowed="false" one_of_allowed="false">
<dt:measure_number_type representation_ref="0161-1#04-000005#1">
<dt:real_type>
<dt:real_format pattern="\d(1,)\.\d(1,)"/>
</dt:real_type>
<dt:prescribed_unit_of_measure UOM_ref="0161-1#05-003260#1"/>
</dt:measure_number_type>
</ig:prescribed_property>
</ig:prescribed_item>
</ig:identification_guide>
EOT
require 'nokogiri'
doc = Nokogiri::XML(xml)
data = [ %w[ class_ref property_ref is_required UOM_ref] ]
doc.css('|prescribed_item').each do |pi|
pi.css('|prescribed_property').each do |pp|
data << [
pi['class_ref'],
pp['property_ref'],
pp['is_required'],
pp.at_css('|prescribed_unit_of_measure')['UOM_ref']
]
end
end
puts data.map{ |row| row.join('|') }
哪个输出:
class_ref|property_ref|is_required|UOM_ref
0161-1#01-765557#1|0161-1#02-016058#1|false|0161-1#05-003260#1
0161-1#01-765557#1|0161-1#02-016059#1|false|0161-1#05-003260#1
您能否更详细地解释这一行“
pp.at_css('|prescribed_unit_of_measure')['UOM_ref']
”
在Nokogiri中,有两种类型的“查找节点”方法:“搜索”方法将所有与特定访问者匹配的节点返回为NodeSet
,“at”方法返回第一个Node
NodeSet
的1}},它将是第一个遇到与访问者匹配的节点。
“搜索”方法包括search
,css
,xpath
和/
。 “at”方法包括at
,at_css
,at_xpath
和%
。 search
和at
都接受XPath或CSS访问者。
返回pp.at_css('|prescribed_unit_of_measure')['UOM_ref']
:代码pp
中的那一点是包含“prescribed_property”节点的局部变量。所以,我告诉代码找到pp
下与CSS |prescribed_unit_of_measure
访问者匹配的第一个节点,换句话说,<dt:prescribed_unit_of_measure>
节点包含的第一个pp
标记。当Nokogiri找到该节点时,它返回节点的UOM_ref
属性的值。
作为一个FYI,/
和%
运算符在Nokogiri中的别名分别为search
和at
。它们是其“Hpricot”兼容性的一部分;当Hpricot是首选的XML / HTML解析器时,我们经常使用它们,但对于大多数Nokogiri开发人员来说,它们并不是惯用语。我怀疑这是为了避免与经常使用操作员混淆,至少在我的情况下是这样。
此外,Nokogiri的CSS访问器具有一些特殊的多汁性;它们支持命名空间,就像XPath访问器一样,只有它们使用|
。 Nokogiri会让我们忽略命名空间,这就是我所做的。您需要了解有关CSS和名称空间的Nokogiri文档以获取更多信息。