【问题标题】:Streaming XML Mime Type?流式 XML Mime 类型?
【发布时间】:2013-06-04 19:42:40
【问题描述】:

我正在构建一个发出流式 XML 的 Web 服务。因此,输出将如下所示(在高层次上):

<fragment1>
    <!-- ... -->
</fragment1>

<fragment2>
    <!-- ... -->
</fragment2>

...等等。对于普通的 XML 文档,您可以使用以下任何一种不同的 MIME 类型:

  • 应用程序/xml
  • application/vnd.mycompany.com.description+xml(根据this lovely answer
  • 文本/xml

但是,这些 MIME 类型都假定响应只包含一个 XML 文档/片段。就我而言,响应包含零个或多个片段。出于这个原因,使用其中一种 MIME 类型似乎是错误的事情。正确的处理程序会(正确地)将响应作为单个 XML 文档处理,并且 (a) 在到达第二个片段时出现错误,或者 (b) 默默地忽略从片段 2 开始的片段。

如果那是错误的事情,那么这些 MIME 类型之一就是正确的事情:

  1. application/octet-stream
  2. application/vnd.mycompany.com.description.streaming+xml
  3. application/vnd.mycompany.com.description+streaming-xml

或者我应该使用一个完全不同的?此外,如果 MIME 类型的相同“样式”可以在该数据格式上线后应用于流式 JSON,那就太好了。

编辑:为了让这个问题更有趣,并提供一个我试图模拟的工作实现示例,这个 API 是在 the Twitter streaming API 之后建模的。

【问题讨论】:

    标签: http mime-types


    【解决方案1】:

    听起来,除了您的流媒体需求之外,您的内容实际上是一个 Multipart message 和几个 application/xml 部分。使用此布局application/json 部分也可以混合在您的消息中。

    如果您的单个 XML 片段是较大文档的一部分,请查看(有些陈旧且低调的)XML Fragment Interchange W3C Candidate Recommendation。它定义了一种很好的语法来将片段主体与有关原始文档的上下文信息包装在一起。

    【讨论】:

    • 我正在努力将内容视为一个使用Transfer-Encoding: chunked 以流媒体方式随时间推移交付的长实体。将其视为多部分很有趣,但我认为这会使线路上的字节更难以流方式解释。 (我不知道有任何 HTTP 客户端可以让您一次使用一个多部分“块”。)这种方法以 Twitter 流 API 为模型。我将把它添加到问题中。 +1 有趣的想法和链接到我以前从未见过的 W3C recco。 :)
    • 引用 API 使用原始内容类型 (application/json) 加上可选的 delimited 参数,该参数将下一条消息的长度嵌入到响应正文中,以便客户端可以知道需要多少字节阅读(就 MIME 类型而言并非严格“正确”,但它肯定是有效的)。
    • 关于一次消耗一个“块”。看看multipart/x-mixed-replace(Old but Godoie)MIME 类型。除了 MSIE 之外,每个主要浏览器都可以正确处理它。那是最初的 HTTP 流机制(不过,我同意库支持很差)。
    • multipart/x-mixed-replace MIME 类型令人着迷。我不知道 IP 摄像机是如何工作的。我同意这是 MIME 的正确答案。
    【解决方案2】:

    根据数据中的语义关系及其结构,有多种选择。

    第一个选项:如果您有一个(连续)文件,可以通过将其包装在 &lt;elem&gt;...&lt;/elem&gt; 标记中轻松将其转换为有效的 XML 文档,则它应该是 application/xml-external-parsed-entity .这可以是任何东西,从简单的文本到 cmets、处理指令或复杂元素的列表。但是,您不能插入 XML 声明(必须通过 MIME 定义字符集)或任何 DTD(因此,如果您依赖 DTD,则必须由封闭文档提供含义,并且您也不能包含任何其他外部解析实体,除非您使用 XInclude)。

    我发现这适用于任何可以描述为任意 XML 内容/片段的内容。它主要用于通过 DTD 中的外部解析实体使用,但它本身也同样有效。如果您的片段可能没有单个根节点,请使用此选项。然而,我可以想到一个警告:如果流是无限的,客户端最终将不得不在某个地方终止它,并且由于没有指定外部边界,它可能会在元素中间终止,根据它使其无效到它的架构。

    您也可以使用application/xml 并自己编写开始标记,但如果配置为将文档作为一个整体进行处理,某些解析器可能会等待文档的结尾。使用application/xml-external-parsed-entity,最好的办法就是将其解析为单个 XML 节点的流。

    第二种选择:multipart类型的范围。这样,您可以包装单个 XML 文档(application/xml 或特定的)或片段(application/xml-external-parsed-entity)。同样,内部类型的选择取决于单个消息是否可以被视为独立的 XML 文档(例如 application/svg+xml 用于“SVG 视频”)。

    子类型的选择取决于整个序列的预期含义。一组单独的独立文件流可以使用multipart/mixed(这是最通用的类​​型)。如果 XML 数据以某种方式相互关联,您可以使用 multipart/related 并将标识符分配给各个片段。最后,如果只有消息的最后一部分表示资源的最新内容(以保存单个请求),则使用 multipart/x-mixed-replace


    为了说明:

    • 如果响应是用 XHTML 标记丰富的文本流(例如从 Markdown 流转换而来),它应该是单个 application/xml-external-parsed-entity

    • 如果碎片是附件、从网站不断下载的文件或用户上传的文件,应该是multipart/mixed

    • 如果片段是大型或不断增长的资源图(不仅仅是 XML)中的节点,则应使用multipart/related

    • 如果结果是一个短暂的信息,比如某个过程的当前状态或某事的持续测量,它应该是multipart/x-mixed-replace

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      • 2019-08-06
      • 2020-05-31
      • 1970-01-01
      相关资源
      最近更新 更多