65.9K
CodeProject 正在变化。 阅读更多。
Home

GraphQuery - 强大的文本查询语言

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2018 年 10 月 25 日

CPOL

3分钟阅读

viewsIcon

8416

GraphQuery 是一种查询语言和执行引擎,可连接到任何后端服务。它是“后端语言无关”的。

GraphQuery CircleCI Go Report Card Build Status Coverage Status GoDoc Gitter chat

GraphQuery

GraphQuery 是一种查询语言和执行引擎,可连接到任何后端服务。它是后端语言无关的。

项目地址:GraphQuery

相关项目

Catalog

  1. 概述
  2. 开始使用
    1. 第一个示例
    2. 管道
  3. Install
    1. Golang
    2. 其他语言

概述

GraphQuery 是一种易于使用的查询语言,它内置了 Xpath/CSS/Regex/JSONpath 选择器以及足够的内置文本处理函数
最令人惊叹的是,您可以使用极简的 GraphQuery 语法获取您想要的任何数据结构

语言无关

使用 GraphQuery,您可以统一任何后端语言的文本解析逻辑。
您无需在不同语言中查找 Xpath/CSS/Regex/JSONpath 选择器的实现,也无需熟悉它们的语法或探索其兼容性。

多选择器语法支持

您可以使用 GraphQuery 解析任何文本,并使用您熟悉的选择器。GraphQuery 目前支持以下选择器:

  • Jsonpath 用于解析 JSON 字符串
  • XpathCSS 用于解析 XML/HTML
  • 正则表达式 用于解析任何文本

您可以在 GraphQuery 中以任何组合使用这些选择器。

完整的功能

Graphquery 包含一些内置的文本处理函数,例如 trimtemplatereplace。如果您认为这些函数不能满足您的需求,您可以在管道中注册新的自定义函数。

开始使用

GraphQuery 由查询语言和管道组成。为了引导您了解每个组件,我们编写了一个示例,旨在说明 GraphQuery 的各个部分。这个示例并不详尽,但旨在快速介绍 GraphQuery 的核心概念。示例的前提是,我们想使用 GraphQuery 查询有关图书馆藏书的信息。

1. 第一个示例

html
<library>
<!-- Great book. -->
<book id="b0836217462" available="true">
    <isbn>0836217462</isbn>
    <title lang="en">Being a Dog Is a Full-Time Job</title>
    <quote>I'd dog paddle the deepest ocean.</quote>
    <author id="CMS">
        <?echo "go rocks"?>
        <name>Charles M Schulz</name>
        <born>1922-11-26</born>
        <dead>2000-02-12</dead>
    </author>
    <character id="PP">
        <name>Peppermint Patty</name>
        <born>1966-08-22</born>
        <qualification>bold, brash and tomboyish</qualification>
    </character>
    <character id="Snoopy">
        <name>Snoopy</name>
        <born>1950-10-04</born>
        <qualification>extroverted beagle</qualification>
    </character>
</book>
</library>

面对这样的文本结构,我们自然会想到从文本中提取以下数据结构:

{
    bookID
    title
    isbn
    quote
    language
    author{
        name
        born
        dead
    }
    character [{
        name
        born
        qualification
    }]
}

这很完美,当您知道要提取的数据结构时,您就已经成功了 80%。上面的就是我们想要的数据结构,我们暂时称之为 DDL(数据定义语言)。让我们看看 GraphQuery 是如何实现的。

graphquery
{
    bookID `css("book");attr("id")`
    title `css("title")`
    isbn `xpath("//isbn")`
    quote `css("quote")`
    language `css("title");attr("lang")`
    author `css("author")` {
        name `css("name")`
        born `css("born")`
        dead `css("dead")`
    }
    character `xpath("//character")` [{
        name `css("name")`
        born `css("born")`
        qualification `xpath("qualification")`
    }]
}

正如您所见,GraphQuery 的语法在 DDL 中添加了一些用`括起来的string。这些由`括起来的string称为Pipeline。稍后我们将介绍 Pipeline。首先,让我们看看 GraphQuery 引擎返回了什么数据给我们。

json
{
    "bookID": "b0836217462",
    "title": "Being a Dog Is a Full-Time Job",
    "isbn": "0836217462",
    "quote": "I'd dog paddle the deepest ocean.",
    "language": "en",
    "author": {
        "born": "1922-11-26",
        "dead": "2000-02-12",
        "name": "Charles M Schulz"
    },
    "character": [
        {
            "born": "1966-08-22",
            "name": "Peppermint Patty",
            "qualification": "bold, brash and tomboyish"
        },
        {
            "born": "1950-10-04",
            "name": "Snoopy",
            "qualification": "extroverted beagle"
        }
    ],
}

太棒了,简直完美。正好是我们想要的。
我们将上述示例称为Example1,现在让我们简要了解一下管道是什么。

2. 管道

管道是函数的集合,它以前一个元素的文本作为输入参数,按顺序执行集合中的函数。例如,我们前面示例中的 language 字段定义如下:graphquery language `css("title");attr("lang")` language 是字段名,css("title"); attr("lang") 是管道。在这个管道中,GraphQuery 首先使用 CSS 选择器从文档中找到 title 节点,然后获得 title 节点。将获得的节点传递给 attr() 函数并获取其 lang 属性。整个过程如下:

language: document->css("title")->attr("lang")->en

Example1中,我们不仅使用了 cssattr 函数,还使用了 xpath()。这很容易关联,Xpath() 是使用 Xpath 选择器来选择元素。以下是 graphquery 当前版本内置的管道函数列表:

pipeline | prototype | example | introduce | ------ | ------ | ------ | ----- | | css | 
css(CSSSelector) | css("title") | Use CSS selector to select elements | | json | 
json(JSONSelector) | json("title") | Use json path to select elements | | xpath | 
xpath(XpathSelector) | xpath("//title") |Use Xpath selector to select elements | | 
regex | regex(RegexSelector) | regex("<title>(.*?)</title>") | 
Use Regex selector to select elements | | trim | trim() | trim() | 
Clear spaces and line breaks before and after the string| | template | 
template(TemplateStr) | template("[{$}]") | Add characters before and after variables| | 
attr | attr(AttributeName) | attr("lang") | Extract the property of the current node| | 
eq | eq(Index) | eq("0") | Take the nth element in the current node collection| | 
string | string() | string() | Extract the current node native string| | text | text() | 
text() | Extract the text of the current node| | link | link(KeyName) | link("title") | 
Returns the current text of the specified key| | replace | replace(A, B) | 
replace("a", "b") | Replace all A in the current node to B|

有关管道和函数的更详细介绍,请访问文档。

安装

GraphQuery 目前仅原生支持 Golang,但对于其他语言,它可以作为服务调用。

1. Golang

go get github.com/storyicon/graphquery

创建一个新的 go 文件

`golang package main
import ( "encoding/json" "log"
"github.com/storyicon/graphquery"
)
func main()
{ document := <html> <body> <a href="01.html">Page 1</a>
<a href="02.html">Page 2</a> <a href="03.html">Page 3</a>
</body> </html> expr := "{ anchor css(\"a\") [ content text() ] }"
response := graphquery.ParseFromString(document, expr)
bytes, _ := json.Marshal(response.Data) log.Println(string(bytes)) }

运行 go 文件,输出如下:

{"anchor":["Page 1","Page 2","Page 3"]}`

2. 其他语言

我们使用 HTTP 协议为开发者提供跨语言解决方案,您可以使用您想使用的任何后端语言查询 GraphQuery,在启动服务后访问指定端口即可。

GraphQuery-http:GraphQuery 的跨语言解决方案

您也可以使用 RPC 进行通信,但目前您可能需要自己实现,因为 GraphQuery 上的 RPC 项目仍在开发中。

同时,我们欢迎贡献者为 GraphQuery 编写其他语言的原生支持代码。

© . All rights reserved.