【问题标题】:Create non-self-closed empty tag with Nokogiri使用 Nokogiri 创建非自封闭空标签
【发布时间】:2015-11-04 14:10:04
【问题描述】:

当我尝试使用 Nokogiri::XML::Builder 创建 XML 文档时:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.my_tag({key: :value})
end

我得到以下 XML 标记:

<my_tag key="value"/>

它是自封闭的,但我需要完整的形式:

<my_tag key="value"></my_tag>

当我在节点(甚至是空格)内传递一个值时:

xml.my_tag("content", key: :value)
xml.my_tag(" ", key: :value)

它会生成完整的标签:

<my_tag key="value">content</my_tag>
<my_tag key="value"> </my_tag>

但如果我传递一个空字符串或nil,甚至是一个空块:

xml.my_tag("", key: :value)

它会生成一个自闭合标签:

<my_tag key="value"/>

我相信应该有一些属性或其他东西可以帮助我,但简单的谷歌搜索没有找到答案。

我在“Building blank XML tags with Nokogiri?”中找到了一个可能的解决方案,但它会将所有标签保存为非自闭。

【问题讨论】:

  • 根据规范,&lt;foo /&gt;&lt;foo&gt;&lt;/foo&gt; 相同,唯一的区别是更短更干净。为什么一定要有第二种形式?是要求还是愿望?由于 XML 文件可能很大,因此当您处理数百万行时,能够使用较短的格式会导致文件更小。
  • 正如我在下面回答的,原因在于 API。它需要完整的标签符号

标签: ruby xml nokogiri


【解决方案1】:

您可以使用 Nokogiri 的 NO_EMPTY_TAGS save option。 (XML 调用自闭合标签empty-element tags。)

builder = Nokogiri::XML::Builder.new do |xml|
  xml.my_tag({key: :value})
end

puts builder.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)
<?xml version="1.0"?>
<my_tag key="value"></my_tag>

每个选项都有一点表示,因此您可以混合搭配您想要的选项。例如,单独设置NO_EMPTY_TAGS 将使您的XML 保留在一行上,没有空格或缩进。如果您仍然希望它为人类格式化,您可以使用 FORMAT 选项按位或 (|)。

builder = Nokogiri::XML::Builder.new do |xml|
  xml.my_tag({key: :value}) do |my_tag|
    my_tag.nested({another: :value})
  end
end

puts builder.to_xml(
  save_with: Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS
)
puts
puts builder.to_xml(
  save_with: Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
             Nokogiri::XML::Node::SaveOptions::FORMAT
)
<?xml version="1.0"?>
<my_tag key="value"><nested another="value"></nested></my_tag>

<?xml version="1.0"?>
<my_tag key="value">
  <nested another="value"></nested>
</my_tag>

列表末尾还有一些 DEFAULT_* 选项已经将选项组合成常见用途。

您的更新提到“它将所有标签保存为非自关闭”,好像您可能只希望这个单个标签实例是非自关闭的,而其余的则自关闭。 Nokogiri 不会生成这样不一致的文档,但如果必须,您可以将一些使用不同选项构建的 XML 字符串连接在一起。

【讨论】:

  • 我暂时将此解决方案用作临时解决方案。问题是所有空标签要么是自封闭的,要么不是。但对于我的极端情况,没关系。谢谢!
  • 出于好奇,为什么只有这一个标签不能自闭?
  • 实际上我不确定是否需要它。我需要完整的封闭标签才能与 API 兼容。我会检查一下。目前的解决方案还可以。
  • 是的,这可能就是你想要的。如果 API 不喜欢这里的自封闭标签,它也不会喜欢它在其他地方。我和很多这样的人一起工作过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 2017-01-20
  • 1970-01-01
相关资源
最近更新 更多