假设我的HTML结构如下:
<div class="veggie">carrot</div>
<div class="veggie">cucumber</div>
<div class="fruit">
<div class="citrus">orange</div>
<div class="citrus">lemon</div>
<div class="berry">grape</div>
</div>
<div class="veggie">lettuce</div>
<div class="dairy">milk</div>
但是这一切都在这样的一行:
<div class="vegetable">carrot</div><div class="vegetable">cucumber</div><div class="fruit"><div class="citrus">orange</div><div class="citrus">lemon</div><div class="berry">grape</div></div><div class="vegetable">lettuce</div><div class="dairy">milk</div>
如何将其翻译为XML:
<veggie>carrot</veggie>
<veggie>cucumber</veggie>
<fruit>
<citrus>orange</citrus>
<citrus>lemon</citrus>
<berry>grape</berry>
</fruit>
<veggie>lettuce</veggie>
<dairy>milk</dairy>
这听起来很简单,但我不知道从哪里开始!
答案 0 :(得分:0)
使用正则表达式执行此操作将是丑陋的,并且可能不可靠。首先,正则表达式不处理具有嵌套结构的语言,HTML具有这种结构。其次,HTML不是一种干净的语言;它充满了错误,浏览器构建者在他们的智慧决定接受,确保HTML编写者进一步草率编程。
一种干净的方法是解析HTML(就像编译器一样,使用“脏”的HTML解析器)并构建一个抽象语法树。 (您可能会使用浏览器DOM)。然后,您将转换应用于HTML AST,以逐步将其转换为XML片段。您可以通过编写临时过程代码来执行后者,执行递归树遍历,检查特殊情况并吐出XML。程序可能看起来很丑陋,因为它正在爬上树节点,测试它,随地吐痰,整个地方,以及你所拥有的更具特色的情况,这会变得更加混乱。
很好的方法是使用program transformation system (PTS)。一个好的PTS将允许您为(脏)HTML和XML定义解析器和prettyprinters;然后您可以解析HTML,PTS将按照前一段中的建议进行AST。 PTS中的值是您通常可以使用源语言和目标语言的“表面语法”来定义转换规则,例如,您可以说“如果您看到此HTML模式,则将其替换为那个XML 模式。这里有几个例子:
rule replace div_class(a: attribute, t: text_content): HTMLnode -> XMLNode
= " <div class=\a>\t<div> "
-> "< \a > \t <\a /> ";
此规则与仅包含文本内容的div的HTML AST(非文本)匹配, 并将其映射到与class属性匹配的XML标记,具有相同的文本内容,与OP想要的部分匹配。双引号是 meta 引号,用于区分重写规则语法与源语言或目标语言语法。匹配部分用HTML语法编写,元变量转义符\ a和\ t对应于满足匹配的值。请注意,由于对t的约束,此规则只能匹配仅包含 文本的HTML标记。替换部分生成所需的XML标记和内容,替换匹配的元变量的值。
对于OP示例中更复杂的部分,HTML内容不仅仅是文本,我们需要这个规则:
rule replace div_class(a: attribute, c: content): HTMLnode -> XMLNode
= " <div class=\a>\c<div> "
-> "< \a > \c <\a /> ";
if ~ match(c,text_content);
\ c将匹配任何内容,因此太一般,但额外的“if”约束检查\ c不是text_content。此规则将在先前规则不会的位置运行,反之亦然。
我认为这涵盖了所有OP的例子,基础知识。
没有任何其他约束,两个规则都会在AST上运行,并且这些规则的应用顺序无关紧要。从概念上讲,每个规则将“黄色”HTML节点转换为“蓝色”XML节点;统称,规则将所有黄色补丁转换为蓝色补丁。
OP可能需要额外的规则来以任何他想要的方式将HTML文档的其他部分翻译成XML; HTML是一种相当大的语言,他可能必须编写一堆规则才能正确填写。关键是他可以在相同的表面语法风格中编写规则[作为一个实际问题,你经常需要在规则中添加一些程序代码,使它们完全粘合在一起,比纯粹的ad hoc少得多办法]。 (将其写为临时代码不会节省任何费用; OP仍然必须处理所有HTML标记类型。)不同的PTS表达规则不同。我正在使用自己的PTS [DMS Software Reengineering Toolkit]中的重写规则语法。理想情况下,PTS已经有了HTML和XML的可用定义; DMS确实。