Skip to main content

Appendix A. Notes on Processing XML Elements (处理 XML 元素的说明)

附录 A. Notes on Processing XML Elements (处理 XML 元素的说明)

A.1. Notes on Empty XML Elements (空 XML 元素的说明)

XML 支持两种机制来指示 XML 元素没有任何内容。第一种是声明形式为 <A></A> 的 XML 元素。第二种是声明形式为 <A/> 的 XML 元素。这两个 XML 元素在语义上是相同的。

A.2. Notes on Illegal XML Processing (非法 XML 处理的说明)

XML 是一种灵活的数据格式, 使得提交看起来合法但实际上不合法的数据变得很容易。"在接受时灵活, 在发送时严格" 的哲学仍然适用, 但不能不恰当地应用。XML 在处理空格、元素排序、插入新元素等问题时非常灵活。这种灵活性不需要扩展, 尤其是在元素含义方面。

接受非法的 XML 元素组合并没有好处。在最好的情况下, 它会导致不需要的结果, 在最坏的情况下, 它会造成真正的损害。

A.3. Example - XML Syntax Error (示例 - XML 语法错误)

以下 PROPFIND 方法的请求主体是非法的。

<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:allprop/>
<D:propname/>
</D:propfind>

propfind 元素的定义仅允许 allprop 或 propname 元素, 而不是两者都有。因此, 上述是错误的, 必须用 400 (Bad Request) 响应。

然而, 想象一下, 如果服务器想要 "友好" 并决定选择 allprop 元素作为真实元素并对其进行响应。通过带宽受限线路运行并打算执行 propname 的客户端如果服务器将命令视为 allprop, 将会大吃一惊。

此外, 如果服务器宽松并决定回复此请求, 结果将在服务器之间随机变化, 一些服务器执行 allprop 指令, 而其他服务器执行 propname 指令。这降低了互操作性而不是增加了互操作性。

A.4. Example - Unexpected XML Element (示例 - 意外的 XML 元素)

前面的示例是非法的, 因为它包含两个明确禁止一起出现在 propfind 元素中的元素。但是, XML 是一种可扩展的语言, 因此可以想象为与 propfind 一起使用定义新元素。下面是 PROPFIND 的请求主体, 像前面的示例一样, 不理解 expired-props 元素的服务器必须用 400 (Bad Request) 拒绝它。

<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:"
xmlns:E="http://www.example.com/standards/props/">
<E:expired-props/>
</D:propfind>

要理解为什么返回 400 (Bad Request), 让我们看看不熟悉 expired-props 的服务器如何看待请求主体。

<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:"
xmlns:E="http://www.example.com/standards/props/">
</D:propfind>

由于服务器不理解 'expired-props' 元素, 根据第 17 节中指定的 WebDAV 特定 XML 处理规则, 它必须将请求处理为好像该元素不存在一样。因此, 服务器看到一个空的 propfind, 根据 propfind 元素的定义是非法的。

请注意, 如果扩展是附加的, 它不一定会导致 400 (Bad Request)。例如, 想象以下 PROPFIND 的请求主体:

<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:"
xmlns:E="http://www.example.com/standards/props/">
<D:propname/>
<E:leave-out>*boss*</E:leave-out>
</D:propfind>

前面的示例包含虚构的元素 leave-out。其目的是防止返回其名称与提交的模式匹配的任何属性。如果将前面的示例提交给不熟悉 'leave-out' 的服务器, 唯一的结果是 'leave-out' 元素将被忽略, 并将执行 propname。