如果XHTML不允许嵌套表单,那么如何/为什么验证呢?这个代码可以使用吗?

If XHTML does not allow nested forms, then how/why does this validate? Is this code ok to use?

提问人:KMurphy 提问时间:2/13/2015 更新时间:2/13/2015 访问量:241

问:

我正在制作一个网页,该网页列出了数据库中的几个租赁预订。我想我可能已经把自己逼到了墙角。我最初让每行以 3 个单元格结尾,每个单元格都包含一个由 2 或 3 个隐藏字段组成的小表单和一个用于“编辑”、“返回”或“取消”预订的按钮。

这些工作正常,并且都有效,因为每个完整的表单都在一个单元格中。

现在,我需要添加功能以允许选择多行,并将它们传递到另一个页面。因此,我不假思索地添加了一个环绕整个表格,在每一行添加了一个复选框,并在表格底部添加了一个提交按钮。<form>

经过一番研究,我很确定 XHTML 中不允许使用嵌套表单。但是该文档仍然以某种方式使用 W3C 验证器进行验证。我正在使用 XHTML 1.0 Transitional。也许是因为它不是直接在另一个里面,而是在里面?这是允许的吗?<form><form><form><table><form>

表单按原样工作(它从顶行提交了一些额外的字段,但如果有必要,我可以忽略这些字段)。

我只是害怕实现这个,因为我觉得这不可能是正确的。如果有人能澄清这是否有效,我将不胜感激。如果不是,你有什么建议可以解决它吗?

提前致谢!

<form id="form2" name="form2" method="post" action="pickup.php">
    <table width="1200" border="1" align="center" cellpadding="5" cellspacing="0" style="border-collapse:collapse; border-color:#CCC;">
        <tr>
            <td colspan="10" bgcolor="#CCCCCC"><h2>Equipment Being Picked Up Today</h2></td>
        </tr>
        <tr class="highlight">
            <td><input type="checkbox" name="res1" id="res1" value="2278" /></td>
            <td>George Washington</td>
            <td>555-333-4444</td>
            <td><a href="product.php?sku=R6209" target="_self">Lghting kit 6209</a></td>
            <td>2/12/15</td>
            <td>2/13/15</td>
            <td></td>
            <td align="center">
                <form name="editForm" method="post" action="edit.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2278" />
                    <input type="submit" name="edit" value="edit" />
                </form>
            </td>
            <td align="center">
                <form name="returnForm" method="post" action="today2.php">
                    <input name="reservationID" type="hidden" value="2278" />
                    <input name="return" type="hidden" value="yes" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input type="submit" value="return" />
                </form>
            </td>
            <td align="center">
                <form name="cancelForm" method="post" action="cancel.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2278" />
                    <input type="submit" name="cancel" value="cancel" />
                </form>
            </td>
        </tr>
        <tr class="highlight">
            <td><input type="checkbox" name="res2" id="res2" value="2279" /></td>
            <td>Sam Adams</td>
            <td>333-222-7777</td>
            <td><a href="product.php?sku=R8300" target="_self">camera kit 3456</a></td>
            <td>2/12/15</td>
            <td>2/13/15</td>
            <td></td>
            <td align="center">
                <form name="editForm" method="post" action="edit.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2279" />
                    <input type="submit" name="edit" value="edit" />
                </form>
            </td>
            <td align="center">
                <form name="returnForm" method="post" action="today2.php">
                    <input name="reservationID" type="hidden" value="2279" />
                    <input name="return" type="hidden" value="yes" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input type="submit" value="return" />
                </form>
            </td>
            <td align="center">
                <form name="cancelForm" method="post" action="cancel.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2279" />
                    <input type="submit" name="cancel" value="cancel" />
                </form>
            </td>
        </tr>
        <tr class="highlight">
            <td><input type="checkbox" name="res3" id="res3" value="2280" /></td>
            <td>Bob Dole</td>
            <td>111-222-4444</td>
            <td><a href="product.php?sku=R8609" target="_self">Other item 6789</a></td>
            <td>2/12/15</td>
            <td>2/13/15</td>
            <td></td>
            <td align="center">
                <form name="editForm" method="post" action="edit.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2280" />
                    <input type="submit" name="edit" value="edit" />
                </form>
            </td>
            <td align="center">
                <form name="returnForm" method="post" action="today2.php">
                    <input name="reservationID" type="hidden" value="2280" />
                    <input name="return" type="hidden" value="yes" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input type="submit" value="return" />
                </form>
            </td>
            <td align="center">
                <form name="cancelForm" method="post" action="cancel.php">
                    <input name="editFrom" type="hidden" value="today2.php" />
                    <input name="theDate" type="hidden" value="2015-02-12" />
                    <input name="reservationID" type="hidden" value="2280" />
                    <input type="submit" name="cancel" value="cancel" />
                </form>
            </td>
        </tr>
        <tr>
            <td colspan="10">
                <input type="submit" name="submit" id="submit" value="Pickup Selected Equipment" />
            </td>
        </tr>
    </table>
</form>
HTML 表单 XHTML

评论

0赞 Guffa 2/13/2015
似乎XHTML验证器允许嵌套表单(也许是DTD可以禁止的限制),但浏览器不允许嵌套表单。请参阅:anderwald.info/internet/nesting-form-tags-in-xhtml(请注意,所提供的解决方法实际上并没有嵌套表单,它只是在第一个“内部”表单之前结束“外部”表单。
0赞 Alohci 2/14/2015
@Guffa - 解决方法确实嵌套了表单。请参阅此解决方法的 Live DOM 查看器示例,HTML 解析真的很奇怪。中断的是表单所有者关联,而不是嵌套。
0赞 Guffa 2/14/2015
@Alohci:如果仅使用变通办法表单标记中的结束标记,则结果是相同的。我不认为表单实际上是嵌套的,只是 DOM 查看器无法显示以与它开始的不同级别结束的表单。
0赞 Alohci 2/14/2015
@Guffa - 这可能只是术语的差异。如果不是关于 DOM,我不知道“嵌套”是什么意思。DOM 的行为与嵌套的表单元素完全相同。例如,在 JS 中,从内部表单元素向上浏览祖先列表将找到外部表单元素。或者在CSS中,将内部形式的文本着色为红色。查看 goo.gl/A1GbJPform form { color:red; }

答:

3赞 Jukka K. Korpela 2/13/2015 #1

它之所以有效,是因为 XHTML 1.0 的形式验证是基于 XML 规则的,而 XML 是对 SGML 的强烈简化修改,而 SGML 是 HTML 4.01 名义上所基于的。因此,基于 XML 的 DTD 中描述的 XHTML 1.0 的正式语法并不禁止所有 HTML 版本中禁止的某些功能(如嵌套表单)。该规范是这样说的:

SGML 使 DTD 的编写者能够排除特定的 元素包含在元素中。此类禁令 (称为“排除项”)在 XML 中是不可能的。

例如,HTML 4 Strict DTD 禁止嵌套“a” 元素到任何后代深度。事实并非如此 可以在XML中阐明此类禁令。即使这些 DTD中不能定义禁止,某些要素不应定义 嵌套。此类要素和不应包含的要素的摘要 嵌套在它们中可以在规范的元素禁令中找到。

元素禁令规定,一个元素不得包含另一个元素formform

嵌套表单是不安全的。没有具体说明如果这样做会发生什么。例如,未指定在提交外部表单时是否应包含内部表单上的字段。

因此,您应该考虑重构页面,以避免表单嵌套。如果您需要这方面的帮助,请考虑发布一个新问题,该问题指定所需的功能并显示您在重组方面的最佳尝试。

评论

0赞 KMurphy 2/13/2015
感谢您的澄清。我知道这是一个坏主意,但我只是想看看它是否真的有效。
0赞 Alohci 2/14/2015
“没有规范......没有具体说明在提交外部表单时是否应包含内部表单上的字段。事实并非如此,HTML5 对此进行了定义。仅包含表单所有者为要提交的表单的字段元素。由于字段元素只能有一个表单所有者,并且默认情况下是其最接近的祖先表单元素(可以显式覆盖),因此对于内部表单中的特定字段是否应包含在外部表单提交中没有歧义。
0赞 Jukka K. Korpela 2/14/2015
@Alohci,我希望你像往常一样在这里,但问题是关于XHTML 1.0的。虽然 HTML5 通常规范了常见的浏览器实践,但它也添加了新功能和新定义,浏览器可能会也可能不会遵守这些功能定义。