【问题标题】:How can I make empty tags self-closing with Nokogiri?如何使用 Nokogiri 使空标签自动关闭?
【发布时间】:2011-03-28 13:40:57
【问题描述】:

我在 ERB 中创建了一个 XML 模板。我在导出过程中用数据库中的数据填充它。

在某些情况下,存在空值,在这种情况下元素可能为空,如下所示:

<someitem>

</someitem>

在这种情况下,接收导出的客户端希望将其转换为自闭合标签:

<someitem/>

我想看看如何让 Nokogiri 做到这一点,但我还没有看到。有人知道如何使用 Nokogiri 使空 XML 标签自动关闭吗?

更新

一个正则表达式就足以完成我上面指定的操作,但是客户端现在还希望其子项全部为空的标签能够自动关闭。所以这个:

<someitem>
  <subitem>

  </subitem>
  <subitem>

  </subitem>
</someitem>

...也应该是

<someitem/>

我认为这需要使用 Nokogiri。

【问题讨论】:

  • 我不明白你更新的自动关闭规则。您似乎建议删除没有内容的节点 (subitem)。但是,如果是这种情况,那么在删除它们之后,父级 (someitem) 也应该被删除,因为它也没有内容。

标签: ruby xml nokogiri


【解决方案1】:

搜索

<([^>]+)>\s*</\1>

替换为

<\1/>

在 Ruby 中:

result = subject.gsub(/<([^>]+)>\s*<\/\1>/, '<\1/>')

说明:

<       # Match opening bracket
(       # Match and remember...
 [^>]+  # One or more characters except >
)       # End of capturing group
>       # Match closing bracket
\s*     # Match optional whitespace & newlines
<       # Match opening bracket
/       # Match /
\1      # Match the contents of the opening tag
>       # Match closing bracket

【讨论】:

  • 这是我在导出过程中最容易有条件地加入的事情。谢谢!
  • @MattHuggins:您的编辑没有多大意义。 \n 已经包含在\s 中,所以[\s\n]\s 完全相同。但是之前的编辑已经很奇怪(出于同样的原因),所以我认为答案应该恢复到原来的形式。你怎么看?
  • @TimPietzcker - 我没有意识到 \n 已经包含在 \s 中。第一次编辑启发了我的第二次编辑。如果你说的是真的,那么我同意恢复原来的答案可能是最好的。 (可能值得更新\s* 的解释,以明确这包括空格和换行符。)
  • 我已经继续并回复了 \s 包含换行符的注释。 :) 感谢您清除它!
【解决方案2】:

几个问题:

  1. &lt;foo&gt;&lt;/foo&gt;&lt;foo /&gt; 是一样的,所以为什么要担心这么小的细节呢?如果由于两者之间的文本节点是"\n" 而在语法上很重要,那么在您的 ERB 模板中进行测试以检查将去那里的值,如果它没有被初始化,则输出自闭合标签?请参阅“Yak shaving”。
  2. 为什么涉及 Nokogiri?您应该能够在 ERB 中生成正确的 XML,因为您可以控制模板。

编辑 - Nokogiri 的行为是不重写解析的 XML,除非它必须这样做。我怀疑您必须删除有问题的节点,然后将其重新插入为空节点以使 Nokogiri 输出您想要的内容。

【讨论】:

  • 我非常同意你的第一点。收到导出的客户要求进行此更改。
  • 然后在 ERB 中进行。第二次通过 Nokogiri 需要很多额外的处理,但没有太多额外的好处。
  • 你说得很好,但由于这 种“刮牦牛”请求,我认为其他客户不会在意,我正在尝试在此客户端的导出任务中有条件地执行此操作。将条件逻辑放在一个地方比放在模板中的多个地方更容易。并且处理开销不是什么大问题,因为这段代码将像每月运行一次,如果需要 30 秒或 10 分钟,我真的不在乎。
  • 当我有一个条件字符串需要在 ERB 中多次输出时,我要么在我的控制器中预定义它,要么在模板顶部创建它并将其分配给一个变量,然后在整个文档中引用该变量。例如,报表中的分页之类的内容在顶部和底部是相同的。
  • 3 年后有人举报这个是否有某种原因?这些问题是修辞性的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
相关资源
最近更新 更多