Skip to content

Commit

Permalink
README.md. Update about tutorial and test case.
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengchun committed Jul 6, 2022
1 parent 58f1252 commit d2eebde
Showing 1 changed file with 170 additions and 68 deletions.
238 changes: 170 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,128 +1,230 @@
jsonquery
====
# jsonquery

[![Build Status](https://travis-ci.org/antchfx/jsonquery.svg?branch=master)](https://travis-ci.org/antchfx/jsonquery)
[![Coverage Status](https://coveralls.io/repos/github/antchfx/jsonquery/badge.svg?branch=master)](https://coveralls.io/github/antchfx/jsonquery?branch=master)
[![GoDoc](https://godoc.org/github.com/antchfx/jsonquery?status.svg)](https://godoc.org/github.com/antchfx/jsonquery)
[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/jsonquery)](https://goreportcard.com/report/github.com/antchfx/jsonquery)

Overview
===

jsonquery is an XPath query package for JSON document, lets you extract data from JSON documents through an XPath expression. Built-in XPath expression cache avoid re-compile XPath expression each query.
# Overview

[jsonquery](https://github.com/antchfx/jsonquery) is XPath query package for JSON document depended on [xpath](https://github.com/antchfx/xpath) package, writing in go.

XPath query for Golang
===
jsonquery helps you easy to extract any data from JSON using XPath query without using pre-defined object structure to unmarshal in go, saving your time.

- [htmlquery](https://github.com/antchfx/htmlquery) - XPath query package for HTML document

- [xmlquery](https://github.com/antchfx/xmlquery) - XPath query package for XML document.

- [jsonquery](https://github.com/antchfx/jsonquery) - XPath query package for JSON document
### Install Package

```
go get github.com/antchfx/jsonquery
```

Getting Started
===
## Get Started

### Install Package
The below code may be help your understand what it does. We don't need pre-defined strcutre or using regexp to extract some data in JSON file, gets any data is easy and fast in jsonquery now.

```go
s := `{
"name":"John",
"age":31,
"female":false,
"city":null
}`
doc, err := jsonquery.Parse(strings.NewReader(s))
if err != nil {
panic(err)
}
// iterate all json objects from child ndoes.
for _, n := range doc.ChildNodes() {
fmt.Printf("%s: %v[%T]\n", n.Data, n.Value(), n.Value())
}
// xpath query
n := jsonquery.FindOne(doc, "//age")
fmt.Printf("age: %.2f", n.Value().(float64))
// select a child node with `age`. = jsonquery.FindOne(doc,"age")
m := doc.SelectElement("age")
```
go get github.com/antchfx/jsonquery

// Output:

```
name: John[string]
age: 31[float64]
female: false[bool]
city: <nil>[<nil>]
```

The default Json types and Go types are:

#### Load JSON document from URL.
| JSON | jsonquery(go) |
| ------- | ------------- |
| object | interface{} |
| string | string |
| number | float64 |
| boolean | bool |
| array | []interface{} |
| null | nil |

For more information about JSON & Go see the https://go.dev/blog/json

## Getting Started

#### Load JSON from URL.

```go
doc, err := jsonquery.LoadURL("http://www.example.com/feed?json")
```

#### Load JSON document from string.
#### Load JSON from string.

```go
s :=`{
"name":"John",
"age":31,
"city":"New York"
"age":31,
"city":"New York"
}`
doc, err := jsonquery.Parse(strings.NewReader(s))
```

#### Load JSON document from io.Reader.
#### Load JSON from io.Reader.

```go
f, err := os.Open("./books.json")
doc, err := jsonquery.Parse(f)
```

#### Find authors of all books in the store.
#### Parse JSON array

```go
s := `[1,2,3,4,5,6]`
doc, _ := jsonquery.Parse(strings.NewReader(s))
list := jsonquery.Find(doc, "*")
for _, n := range list {
fmt.Print(n.Value().(float64))
}
```
// Output: `1,2,3,4,5,6`

#### Convert JSON object to XML
```go
doc, _ := jsonquery.Parse(strings.NewReader(s))
fmt.Println(doc.OutputXML())
```

### Methods

#### FindOne()

```go
list := jsonquery.Find(doc, "store/book/*/author")
// or equal to
list := jsonquery.Find(doc, "//author")
// or by QueryAll()
nodes, err := jsonquery.QueryAll(doc, "//a")
n := jsonquery.FindOne(doc,"//a")
```

#### Find the third book.
#### Find()

```go
book := jsonquery.Find(doc, "//book/*[3]")
list := jsonquery.Find(doc,"//a")
```

#### Find the last book.
#### QuerySelector()

```go
book := jsonquery.Find(doc, "//book/*[last()]")
n := jsonquery.QuerySelector(doc, xpath.MustCompile("//a"))
```

#### Find all books that have an isbn number.
#### QuerySelectorAll()

```go
list := jsonquery.Find(doc, "//book/*[isbn]")
list :=jsonquery.QuerySelectorAll(doc, xpath.MustCompile("//a"))
```

#### Find all books priced less than 10.
#### Query()

```go
list := jsonquery.Find(doc, "//book/*[price<10]")
n, err := jsonquery.Query(doc, "*")
```

Examples
===
#### QueryAll()

```go
func main() {
s := `{
"name": "John",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}`
doc, err := jsonquery.Parse(strings.NewReader(s))
if err != nil {
panic(err)
}
name := jsonquery.FindOne(doc, "name")
fmt.Printf("name: %s\n", name.InnerText())
var a []string
for _, n := range jsonquery.Find(doc, "phoneNumbers/*/number") {
a = append(a, n.InnerText())
}
fmt.Printf("phone number: %s\n", strings.Join(a, ","))
if n := jsonquery.FindOne(doc, "address/streetAddress"); n != nil {
fmt.Printf("address: %s\n", n.InnerText())
}
list, err := jsonquery.QueryAll(doc, "*")
```

#### Query() vs FindOne()

- `Query()` will return an error if give xpath query expr is not valid.

- `FindOne` will panic error and interrupt your program if give xpath query expr is not valid.

#### OutputXML()

Convert current JSON object to XML format.

# Examples

```json
{
"store": {
"book": [
{
"id": 1,
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"id": 2,
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"id": 3,
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"id": 4,
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}

```

#### Tests

| Query | Matched | Native Value Types | Native Values |
| ------- | -------------| -------- | -------------|
| `//book` | 1 | []interface{} | `{"book": [{"id":1,... }, {"id":2,... }, {"id":3,... }, {"id":4,... }]}` |
| `//book/*` | 4 | [map[string]interface{}] |`{"id":1,... }`, `{"id":2,... }`, `{"id":3,... }`, `{"id":4,... }` |
| `//*[price<12.99]` | 2 | slice, [map[string]interface{}] | `{"id":1,...}`, `{"id":3,...}` |
| `//book/*/author` | 4 | []string | `{"author": "Nigel Rees"}`, `{"author": "Evelyn Waugh"}`, `{"author": "Herman Melville"}`, `{"author": "J. R. R. Tolkien"}` |
| `//book/*[last()]` | 1 | map[string]interface {} | `{"id":4,...}` |
| `//book/*[1]` | 1 | map[string]interface {} | `{"id":1,...}` |
| `//book/*[2]` | 1 | map[string]interface{} | `{"id":2,...}` |
| `//*[isbn]` | 2 | [map[string]interface{}] | `{"id":3,"isbn":"0-553-21311-3",...}`,`{"id":4,"isbn":"0-395-19395-8",...}` |
| `//*[isbn='0-553-21311-3']` | 1 | object, map[string]interface{} | `{"id":3,"isbn":"0-553-21311-3",...}` |
| `//bicycle` | 1 | object, map[string]interface {} | `{"bicycle":{"color":...,}}` |
| `//bicycle/color[text()='red']` | 1 | map[string]interface {} | `{"color":"red"}` |
| `//*/category[contains(.,'refer')]` | 1 | string | `{"category": "reference"}` |
| `//price[.=22.99]` | 1 | float64 | `{"price": 22.99}` |
| `//expensive/text()` | 1 | string | `10` |

For more supports XPath feature and function see https://github.com/antchfx/xpath

0 comments on commit d2eebde

Please sign in to comment.