规范 XML:纯元素容器中的空格?

Canonical XML: whitespace in element-only container?

我有一个带有 XSD 模式的简单 XML 文件,其中允许某些元素仅包含某些元素,例如

<xsd:element name="day" type="xsd:date"/>
<xsd:element name="interval">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="day" minOccurs="2" maxOccurs="2"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

和XML代码:

<interval>
    <day>2016-08-21</day>
    <day>2016-10-21</day>
</interval>

如果我在 interval 标签中键入空格或 day 以外的任何内容,它将(正确地)验证失败。现在,使用 python 中的 lxml,我提取了此类 XML 的规范版本 (C14N),我发现保留了空格(那 4 个缩进空格)(作为 standard 说)。

然后我需要 digitally sign 这份文件,但我不明白 为什么会有人在那个空格上签名 。这对我来说似乎是一个弱点:不同的缩进意味着不同的规范XML(以及不匹配的签名);但这是一个明确的情况,其中空白与表示的数据无关(更何况架构不会针对任何有意义的内容进行验证)。

我更具体地考虑 whiteSpace facet。通过指定 collapse 验证时应删除空格;但似乎 whiteSpace 不能应用于 complexType,而且我找不到将它与 sequence.

结合的方法

Why is that whitespace part of a canonical representation of an XML involved in digital signatures?

很难回答 "why" 问题,即使您是发布规范的工作组的成员(我不是)。我不知道规范作者为什么做出那个决定,但我认为无论哪种方式的决定都会以牺牲其他用户为代价给一些用户带来不便。

Is there any way of enforcing in the XSD the removal of such useless whitespace?

纯元素内容模型中元素之间的空白在 PSVI 中不被认为是重要的。如果您想物理删除它,一种实用的方法是使用模式感知 XSLT 或 XQuery 处理器复制经过验证的文档,例如

java net.sf.saxon.Query -s:input.xml -xsd:input.xsd -val:strict -qs:.

(查询“.”这里returns验证后的输入文档)

Can I apply the whiteSpace facet to a complexType (element only) node?

不,你不需要。

以下信息由 Pietro Saccardi 在对我的回答进行的编辑中提供,我已将其分离出来,以免显得我是作者。

在带有 lxml 的 python 中,有一个 remove_blank_text 选项会在解析时删除它:

parser = etree.XMLParser(remove_blank_text=True)
xml = etree.parse('file.xml', parser=parser)

MHK观察(来自文档):

请注意,如果 remove_blank_text 选项对文档的可忽略空白没有明确的了解,它也会使用启发式方法。它会将出现在非空白文本节点之后的空白文本节点保持在同一级别。这是为了防止文档样式 XML 丢失内容。

这意味着 remove_blank_text 不是在查看架构或 DTD 来识别纯元素内容,而是从实例数据中进行猜测。这意味着它可能会从

这样的元素中删除空格
<padding>    </padding>

具有简单内容而不是纯元素内容。