因此,假设我有一个类似于以下内容的构建器模板:
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.environment do |environment|
environment.title title
environment.feed feed
environment.status status
environment.description description
# many many more
end
end
builder.to_xml
如果feed
和description
为nil
,则可以输出:
<?xml version="1.0" encoding="UTF-8"?>
<environment>
<title>title</title>
<feed/>
<status>status</status>
<description/>
</environment>
我宁愿完全忽视nils。 实现这一目标的最佳方式是什么?
所需的输出:
<?xml version="1.0" encoding="UTF-8"?>
<environment>
<title>title</title>
<status>status</status>
</environment>
当前解决方案:
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.environment do |environment|
environment.title title if title
environment.feed feed if feed
environment.status status if status
environment.description description if description
# many many more
end
end
builder.to_xml
有更清洁的方式吗?
这对Builder#initialize来说是否是一个有用的选项?
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8', :empty_nodes => false)
答案 0 :(得分:1)
这取决于你真正有多少个字段, 但我的建议是,你已经通过手动输入每个错误而犯了错误。
如果顺序无关紧要,只需使用哈希。 (否则使用OrderedHash)
fields = {
:title => title,
:feed => feed,
:status => status,
:description => description,
# many more
}
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.environment do |environment|
fields.each do |field_name, field_value|
if field_value
environment.send(field_name, field_value)
end
end
end
end
builder.to_xml
似乎有效。
它不漂亮,但至少你只需要在一个地方定义你的字段和值。 优选对象方法?
答案 1 :(得分:1)
我知道这个问题已经过时并且已经有了答案,但是只花了一点时间来解决这个问题,这个问题的快速解决方案(尽管可能不具备性能)位于Nokogiri::XML::Node#traverse
。
一旦您构建了文档,您只需要遍历一次,检查空标记并随时删除它们,如下所示:
builder.doc.traverse do |node|
node.remove if node.element? && node.text == ""
end
请注意#traverse
会返回上一次操作的结果,因此请确保在完成遍历后返回一些内容(您的构建器或XML字符串)。