Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F中的模式匹配XML# 新图书馆:_Xml_F#_Pattern Matching_Dsl_Fparsec - Fatal编程技术网

F中的模式匹配XML# 新图书馆:

F中的模式匹配XML# 新图书馆:,xml,f#,pattern-matching,dsl,fparsec,Xml,F#,Pattern Matching,Dsl,Fparsec,这个问题导致F#3.0中出现了一个与流和类型无关的、非线性的、可扩展的parsec实现——灵感来自FParsec,摆脱了字符和线性流,简化了: 图案 1=;* 2=|[1.l

这个问题导致F#3.0中出现了一个与流和类型无关的、非线性的、可扩展的parsec实现——灵感来自FParsec,摆脱了字符和线性流,简化了:


图案
1=;<~s>*
2=|[1.l<2.l];<~s>*
3=[1.l<3.l]
在哪里

元素名称未指定
字体、bbox和s是属性
V=字符串,N=字符串
?  :: V->bool--值包含字符串
!  :: V->bool=不。(?)--值不包含字符串
~::N->bool--属性N的值为空或空白
F::V->[(N,float)]--从值中提取命名的float列表
RM::V->bool--值与正则表达式匹配
[]:[bool]——条件列表
代码
opensystem.Xml.Linq
open System.Collections.Generic
让内联(-?-)AB=(a:字符串)。包含b
让内联(~~)s=s |>String.IsNullOrWhiteSpace
让内联(!>)x=(^a:(静态成员op_隐式:^b->^a)x)
让内联(@)(x:XElement)n=让a=x.Attribute(!>n)如果为空,则让a.Value else String.Empty
让内联(@n,v)
XE类型=XElement IEnumerator
让内联bbox e=(e@“bbox”)|>趣味s->s.拆分[|“”|]|>Seq.map float |>Seq.toList
让内联左bbox=将bbox与l::->l | 124;->nan匹配
在Seq.iter e@<“class-”+n左键中标记n=let id=Guid.NewGuid()
而n.MoveNext()和&&~(n.Current@“s”)do()
设c2=n.电流
如果(c2@“字体”)-?-“粗体”|>非
然后让l2=c2 |>bbox |>向左
如果l1标记“扬声器”
而n.MoveNext()和&&~(n.Current@“s”)do()
设c3=n.电流
如果(c3@“字体”)-?-“粗体”|>非
然后让l3=c3 |>bbox |>向左
如果l1标记“扬声器”
let测试(x:XElement)=
设span=x.子体(!>“span”)|>Seq.toArray
对于i=29至跨度。长度-1 do
设n=(span |>Seq.skip i).GetEnumerator()
n、 MoveNext()|>忽略
发言人
输入

输出


问题: 要自动从简洁的模式声明转换为运行代码,我考虑执行以下操作:

  • 使用FParsec将模式声明解析为AST
  • 评估AST
但在我做任何事情之前,我想知道:

  • 任何人都可以编写(应用性)EDSL(/部分)来直接使用F#函数和组合声明代码,而不必求助于ASTs吗
  • 是否有一个库能够在XML上进行类似的模式匹配
  • 有人对我的方法有什么意见吗

  • 在我看来,实现这种功能的最好方法是将它放在XLinq(LINQ到XML)之上。与“手动”实现所有模式匹配逻辑相比,它可能更易于编码,更易于维护,并提供同等(如果不是更好的话)性能

    请注意,您仍然可以使用DSL定义要匹配的模式。基本上,您将使用FParsec将DSL解析为AST,然后遍历AST并将其转换为等效的LINQ查询(请参阅)。一旦有了表示查询的LINQ表达式,就可以将其应用于任意数量的
    XDocument
    s来执行模式匹配

    您可能还对阅读Erik Meijer的论文感兴趣,该论文从功能设计的角度讨论了XML编程。

    对于问题2:

    我认为我不理解F#代码,但我用Pascal(,)编写了一个xml模式匹配,您可能想看看。(尽管我将模式称为“模板”,它只选择xml节点,不修改它们)

    用我的模板,这个

    <doc>
    <block>
      <line>
        <span>{.}</span>*
      </line>*
    </block>*
    </doc>
    
    
    {.}*
    *
    *
    
    将匹配输入中的所有跨度。(就像
    {.}*

    或者另一个例子:

    <doc>
    <block>
      <line>
        <span font="TimesNewRoman,Bold">{@s}</span>*
      </line>*
    </block>*
    </doc>
    
    
    {@s}*
    *
    *
    

    将匹配包含说话人姓名的属性。

    我不完全确定问题是什么。您是想使用一些已经存在的XML模式匹配语言(如您的示例中所示),还是希望了解XML处理的一般情况

    LINQ to XML正如Jack p所说,F#中XML处理的最佳选择可能是只使用标准的
    Seq
    函数。这会有点长,但可读性很强

    XPath另一种选择是使用XPath,这是在XML中选择节点的非常简洁(且完全标准)的方法。例如,要选择具有指定属性值的节点,可以编写:

    #r "System.Xml.Linq"
    open System.Xml.Linq
    open System.Xml.XPath
    
    let doc = XDocument.Parse("<r><a n=\"f\">foo</a><a n=\"b\">bar</a></r>")
    doc.XPathSelectElement("//a[@*='f']").Value
    

    请注意,模式是由F#编译器进行类型检查的。

    感谢您提供了指向代码段的链接。我对明显不需要引号o_o感到惊讶。我相信这段代码将非常有用。我决定创建一个类似于FParsec的简单库,但它适用于XElement流,而不是Char流。@CetinSert这听起来非常有趣和有趣的项目!虽然我认为它需要比FParsec有点不同,因为它应该在(XML)树上工作,而不是在(char)列表上工作。另一方面,XML通常需要的查询非常简单,因此
    printfn "Matches: %A" (!/foo/bar/(baz@=true)/quux/= x)
    printfn "Doesn't Match: %A" (!/foo/bar/(baz@=false)/quux/= x)
    printfn "Values: %A" (!/foo/bar/quux/(baz@=42)/! x)