在 SGML 社区中,您正在寻找的值(当它们涉及元素时)被称为“完全限定的通用标识符”或 FQGI;因为 '。' 是 XML 中的合法名称字符,在 SGML 参考具体语法中,FQGI 通常用斜线书写,您正在书写点。(我将在这里延伸术语 FQGI 并用它来表示您感兴趣的字符串,包括表示属性而不是元素的字符串。)
对于查找所有 FQGI 集合的过程,我不知道任何既定术语,这些 FQGI 可能出现在针对特定模式有效的文档中。请记住,在许多 XML 词汇表中,这是一个无限集;如果您想要一个终止的进程,您将需要识别所有可能的 FQGI 的有限子集。
但是您需要遵循的过程相对简单。一个简单的版本是这样运行的:
如果您感兴趣的模式是跨多个模式文档定义的,请将它们全部组合到单个 XML 文档(具有多个 xs:schema 子项的包装器)或可以使用 XSLT 或 XQuery 处理的模式文档的单个集合中。
确定您希望开始的元素声明和属性声明集。(在你的例子中,这个集合大概由 foo 的顶级元素声明组成。)对于这个集合中的每个项目,写下它的名称和它的类型。将这组字符串/类型对称为 S。
将集合 S 复制到集合 S' 中。
按以下方式创建集合 S'':从 S'' 为空开始,然后对于 S' 中的每个项目,令 N 为 FQGI,T 为项目中命名的类型,并且:
(a) 如果 N 表示一个属性,那么什么也不做。
(b) 如果 N 表示一个元素,则识别可能出现在该元素上的属性集。对于每个这样的属性,确定其类型 T2,并通过连接 N、斜杠、at 符号和属性的扩展名称来创建字符串 N2。将 (N2, T2) 对添加到 S''。
(c) 如果 N 表示一个元素,则找到 (i) 出现在 T 的内容模型中,(ii) 匹配 T 的内容模型中的通配符,或 (iii) 可替换的元素集合(i) 或 (ii)。对于每个这样的可能的孩子,识别孩子的类型 T3 并通过连接 N、“/”和可能的孩子的扩展名称来创建一个字符串 N3。将 (N3, T3) 对添加到 S''。
如果 S'' 为空,你就完成了,你的答案在集合 S 和集合 S' 的并集中。否则,令(a new) S 为S 和S' 的并集,令(a new) S' 等于S'',并进行步骤4。
稍加思考就会告诉您,可以匹配通配符的名称集是无限的,因此步骤 4(c) 中的列表 (ii) 无法完整处理。您可以通过多种方式选择列表的有限子集;您选择哪个取决于您想要 FQGI 列表的用途。
稍加思考就会告诉您,如果词汇表中的任何元素都可以作为其自己的后代出现(如 HTML 的 div 或 li 元素),那么概述的过程将永远不会终止。同样,有多种方法可以修剪 4(c) 中生成的对集合以保证终止。
我不知道有什么库可以做到这一点,也许是因为对于有趣的 XML 词汇表来说,可能的 FQGI 集很少是有限的。使用 XQuery 引擎或在 XSLT 样式表中完成这项工作很容易。