SAX解析 - 回显一个不带关闭标记的HTML元素

时间:2011-09-06 13:25:22

标签: html perl parsing language-agnostic sax

使用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中是否有一种直接回显元素的方法,而不是从传递给事件处理程序的内容中重构元素?

2 个答案:

答案 0 :(得分:3)

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

如果你想破解它,那么这就是你能做的。实现characters()回调,如果存在任何非空白字符,将设置标志。 start_element()回调将重置此标志。如果未设置标志,end_element()回调将认为标记为空,并相应地编写语法。

请注意,这也会捕获<td></td>等标记,并将其转换为<td />

答案 1 :(得分:2)

如果没有维护这些元素的列表,我该怎么办?

没什么:/通常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