我已经在一个项目上工作了一个月左右,以便在 javascript 中开发一个 XML 验证器 (XSD)。我已经非常接近但不断遇到问题。
我唯一做得好的是将模式结构规范化为我存储在 DOM 中的 FSA。我尝试了几种方法来针对 FSA 验证我的 xml 结构,但每次都失败了。
验证器用于运行客户端所见即所得 XML 编辑器,因此它必须满足以下要求
- 必须高效(即使使用复杂的模型也需要 < 15ms 来验证元素子节点模式)
- 必须公开一个验证后架构信息集 (PSVI),可以查询该信息集以确定可以在各个点从文档中插入/删除哪些元素,并且仍然保持文档有效。
- 必须能够验证 xml 子节点结构,如果无效,则返回预期的内容或未预期的内容。
-- 更多信息 考虑以下示例--
首先,我将模式结构转换为通用 FSA 表示,以规范化 xs:group 和 xs:import 等与命名空间相关的内容。例如考虑:
<xs:group name="group1">
<xs:choice minOccurs="2">
<xs:element name="e2" maxOccurs="3"/>
<xs:element name="e3"/>
</xs:choice>
</xs:group>
<xs:complexType>
<xs:seqence>
<xs:element name="e1"/>
<xs:group ref="group1"/>
</xs:sequence>
<xs:complexType>
将转换为类似的广义结构:
<seq>
<e name="e" minOccurs="2"/>
<choice minOccurs="2">
<e name="e2" maxOccurs="3"/>
<e name="e3"/>
</choice>
</seq>
我通过 XQuery 和 XSLT 在服务器端完成这一切。
我第一次尝试构建验证器是在 javascript 中使用递归函数。在此过程中,如果我发现可能存在的内容,我会将其添加到全局 PSVI 中,表明它可以添加到层次结构中的指定点。
我的第二次尝试是迭代的,而且速度更快,但两者都遇到了同样的问题。
这两种方法都可以正确验证简单的内容模型,但是一旦模型变得更加复杂和非常嵌套,它们就会失败。
我在想我是从完全错误的方向来解决这个问题的。根据我的阅读,大多数 FSA 都是通过将状态推送到堆栈来处理的,但我不确定在我的情况下如何做到这一点。
我需要关于以下问题的建议:
- 状态机在这里是正确的解决方案吗,它会实现顶部所述的目标吗?
- 如果使用状态机将模式结构转换为 DFA 的最佳方法是什么?汤普森算法?我是否需要优化 DFA 才能使其正常工作。
- 用javascript实现这一切的最佳方式(或最有效的方式)是什么(注意优化和预处理可以在服务器上完成)
谢谢,
凯西
附加编辑:
我一直在看这里的教程:http: //www.codeproject.com/KB/recipes/OwnRegExpressionsParser.aspx专注于正则表达式。它似乎与我需要的非常相似,但专注于为正则表达式构建解析器。这带来了一些有趣的想法。
我认为 xml 架构分解为只有几个运算符:
序列 -> 连接
选择 -> 联合
minOccurs/maxOccurs - 可能需要的不仅仅是 Kleene Closure,不完全确定表示此运算符的最佳方式。