Javascript 根据RNG模式的XML自动完成

Javascript 根据RNG模式的XML自动完成,javascript,xml,fsm,relaxng,Javascript,Xml,Fsm,Relaxng,让RNG成为RELAXNG规范,XML成为相对于RNG的有效XML文档,指定n为XML文档的n第个字符,B是XML和XML[n=B]的节点在字符n处插入节点B的XML文档 我想定义一个函数suggest(RNG,XML,n)→ {Node}=O这样 对于任何B∈ O,XML[n=B]是相对于RNG的有效XML文档 对于任何C∉ O,XML[n=C]无效 目前,我尝试了两种方法: 对XML和RNG使用双递归,在元素XML[n]处,包含n字符和RNGRNG[n]匹配XML[n],并返回元组(布

RNG
成为RELAXNG规范,
XML
成为相对于
RNG
的有效XML文档,指定
n
XML
文档的
n
第个字符,
B
XML
XML[n=B]的节点
在字符
n
处插入节点
B
的XML文档

我想定义一个函数
suggest(RNG,XML,n)→ {Node}=O
这样

  • 对于任何
    B∈ O
    XML[n=B]
    是相对于
    RNG
    的有效XML文档
  • 对于任何
    C∉ O
    XML[n=C]
    无效

目前,我尝试了两种方法:

  • XML
    RNG
    使用双递归,在元素
    XML[n]
    处,包含
    n
    字符和RNG
    RNG[n]
    匹配
    XML[n]
    ,并返回元组
    (布尔值,建议)
    ,然后根据这两个元素决定下一步返回什么。例如,如果当前
    RNG
    节点是
    a
    B
    之间的一个选择,如果
    fn(a)[0]
    为真且
    fn(B)[0]
    为假,则返回
    (真,fn(a)[1])
    ,如果两者均为假,则返回
    (真,fn(a)[1])
    可能不太糟糕,但肯定不总是正确的答案

  • 使用一个“状态机”,有四个堆(比如说
    *r
    RNG[n]
    的子堆,
    *x
    XML[n]
    的子堆,
    *c
    和正在解决的当前选择,以及
    *s
    和输出建议),以便

    • 如果
      *r
      等于
      *x
      ,则弹出
      *r
      *x
      ,如果
      *r
      不等于
      *x
      ,则弹出
      *r
      并将其推入
      *s
    • 如果
      *r
      a
      B
      之间的选择,则在
      *c
      中按
      (*r,*x,B,null)
      ,在
      *r
      中按
      a
    • 如果
      *r
      是ref,则将其弹出并推送匹配的定义,如果是定义,则将其作为一个组进行处理
    • 如果
      *r
      是一个组,则将其元素推送到
      *r
    • 如果
      *c[0]
      等于
      *r
      ,并且
      *c[2]
      是一个节点,则弹出它,将
      *r
      *x
      分别设置为
      *c[2]、*c[0]
      *c[1]
      ,在
      *c
      中按
      (*r、*x、null、*s)
    • 如果
      *c[0]
      等于
      *r
      *c[2]
      为空,则弹出它,比较
      *s
      *c[3]
      ,然后决定(这很难),保留哪一个
    • 根据选择和组简化其他节点(不太难),使它们只有两个元素
    但两者都没有那么成功:

  • 在大型模式上,这两种方法都非常慢
  • 第一个经常失败,因为递归太多,特别是当RNG包含多个
    s时,并且检查无限循环也变得非常困难
  • 第二个使用了大量内存,因为我必须在遇到的每个
    上深度复制每个XML节点
  • 编写测试很难,因为可能的案例太多了,而且我找不到一种通过编程生成测试的方法。所以实际上,我甚至不确定我的函数是否生成了有效的XML文档
  • 我仍然不清楚应该如何处理
    s。例如,以
    :我应该如何对其进行编码,以便建议所有有效节点

  • 我知道多个编辑器(例如Emacs)提供了此选项,但我不确定它们是否确实生成了有效的文档,而且我对Lisp还不够熟悉

    因此,我正在寻找一种在DOM上实现这一点的“好方法”,或者更好的JavaScript库来实现这一点