【问题标题】:SAX Parsing - echoing an HTML element that doesn't take a close tagSAX Parsing - 回显不带关闭标记的 HTML 元素
【发布时间】:2011-09-06 13:25:22
【问题描述】:

使用 perl 的 XML::SAX 模块我正在解析 (x)html 模板,结果只是将大量输入回显到输出。我有一个 SAX 事件处理程序,它扩展了 XML::SAX::Base 并实现了常用方法 - start_elementend_element 等等。

现在我的问题涉及不带结束标记的元素 - 例如<img /><link /><input />。解析器将为这些标签调用start_element($element_name, %attribute_hash)end_element,但是我怎么知道元素是自包含的?

换句话说,我想写出<img src="blah" />,而不是<img ...></img> 我认为是无效的。

没有维护这些元素的列表,我该怎么办?在 SAX 中有没有办法直接回显一个元素,而不是从传递给事件处理程序的内容中重建它?

【问题讨论】:

  • <img></img> 不是无效的(尽管<img>...</img> 是无效的),它只是不兼容 HTML。
  • @Quentin,是的,我打错了图像示例,现在更正了。但是即使添加一个结束标签对于图像来说是可以的,我相信对于其他元素来说就不行了吗?
  • 在 XML(以及 XHTML)中,<foo /><foo></foo> 的含义完全相同,因此两者都是有效的。导致问题的是HTML compatibility,您不应该期望通用 XML 工具能够处理它,您需要对兼容性规则进行特殊处理。

标签: html perl parsing language-agnostic sax


【解决方案1】:

首先,根据 Quentin 的评论,您正在使用 XML 解析器来处理 HTML。只要 HTML 相对干净,这并没有什么特别的问题。但是,如果您需要遵守 HTML(而不是 XHTML),那么 XML 解析器可能是错误的工具。

如果您想破解它,那么您可以这样做。实现一个characters() 回调,如果存在任何非空白字符,它将设置一个标志。 start_element() 回调将重置此标志。如果未设置标志,end_element() 回调将认为标签为空并相应地编写语法。

请注意,这也会捕获像<td></td> 这样的标签,将它们转换为<td />

【讨论】:

  • 是的好主意。没有关于折叠 td 的问题。然而,在某些情况下你不能崩溃——也许是
  • 好的,我要做的是维护一个空 html 元素列表。我不会为这些人写一个关闭标签,但我会为其他所有东西写。所以什么都不会被折叠,但至少会是有效的 HTML 4.01,这实际上是我想要的,而不是有效的 xhtml。
【解决方案2】:

缺少维护这些元素的列表,我该怎么办?

Nothing :/ 通常 DTD 维护这个列表,所以你会在发出结束标记之前询问 dtd 对象......但是 XML::SAX 似乎不支持这样的事情,因为它不支持验证

另一个选项是保持状态,这样你就知道元素何时为空,并省略结束标记,但这也很糟糕 :) 就像维护你自己的列表一样

在 SAX 中有没有办法直接回显一个元素,而不是从传递给事件处理程序的内容中重构它?

不,SAX 没有指定这样的事情,请参阅Echoing an XML File with the SAX Parser 的规范/参考实现

另一方面,XML::Twig 确实提供了这一点,请参阅文档

pretty_print => 'indented',                # output will be nicely formatted
empty_tags   => 'html',                    # outputs <empty_tag />

你想使用 XML::Twig

【讨论】:

  • 感谢您的建议。我去看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 2010-12-26
相关资源
最近更新 更多