有没有办法通过XSD架构限制XML文档包含外部实体引用?

时间:2013-08-13 14:14:16

标签: xml xsd xml-validation

XML文件用作REST Web服务之间的数据交换格式。这些服务的设计使得XML文件中不需要外部实体引用。我想要的是有一个XSD架构来阻止这样的引用。

我对此的想法是创建一个使用正则表达式的模式文件,如:

<xs:simpleType name="stringValue">
    <xs:restriction base="xs:string">
        <xs:pattern value="^[a-zA-Z -]{2,32}$" />
    </xs:restriction>
</xs:simpleType>

如果像<foo>&externalRef</foo>这样的实体得到验证,它将失败,因为&符号不是正则表达式的一部分!

要实现这一目标还有哪些措施?

1 个答案:

答案 0 :(得分:2)

不,您想要的约束不能用XSD表达。

XSD在XML信息集上运行(通常由XML解析器生成),构成其输入的信息项不保留有关XML文档原始实体结构的信息。

那些(像你一样)希望在XML输入中禁止实体引用的人通常通过特殊规则来实现这一点,或者如果他们在信息集级别上通过规则禁止信息集反映存在文件类型声明。

[后来添加] 最后一点似乎难以消化。考虑一个规范(例如SOAP规范),它希望在XML信息集层面定义其操作和约束,而不是在XML字符流层面。它想要,即谈论元素和属性,而不是尖括号。同时,它希望禁止实体引用。这样的规范不能禁止使用在XSD中编写的约束(或在DTD,或者Relax NG,或者Schematron中,......)的实体引用 - 因为所有这些也在信息集级别运行,并且在级别中没有实体引用它们运行的​​抽象。但是任何规范都可以限制信息集的集合,这些信息集可以作为符合过程的输入。(毕竟,当我们说'根元素必须是名字foo时,我们正在做的事情:bar并且有一个baz属性',对吧?我们定义了一个符合标准的处理器应该支持的输入信息集。)所以那些像SOAP一样想要在信息集层面定义东西,并且也想像SOAP那样想要的规范禁止实体引用,通常(至少在我的经验中)说“document information item不得在其子女中包含任何document type declaration information item。”这种技术可能对标准书呆子和语言律师很重要,但是对于那些关心XML和XML标准的人来说,理解这两者很重要w SOAP禁止实体引用,以及为什么它包括我作为一个坏主意。 [结束添加]

由于格式良好的XML文档中的所有实体引用都引用了文档类型定义中声明的实体,因此缺少文档类型声明就足以使所有实体都不是预定义的实体(lt,{{ 1}},gtapos)是不可能的。

你的技术问题现在已经回答了,但如果我没有指出,我可以想象你的目标是不明智的,那么我会失职。

如果你和其他人(比如SOAP的发明者)允许XML文档的创建者使用指定的XML,那么世界将(在这里说)是一个更好的地方。 可能看不到实体引用,管理您没有责任的系统的人可能会看到这样的需求。你真的认为你比他们更了解他们的系统和工作流程吗?为什么要通过定义XML的特殊子集而不是在指定和实现时使用它来为自己和他人工作?对此的通常反应是对十亿次笑声的恐惧,这是一种完全虚假的论点。通过让XML解析器对实体替换文本的最大长度施加限制,或者通过在具有操作系统强加的资源限制的进程中运行XML解析器(以及处理不可信输入的其他进程)来更好地处理资源攻击。