jsonquery

package module
v1.3.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2024 License: MIT Imports: 11 Imported by: 94

README

jsonquery

Build Status GoDoc Go Report Card

Overview

jsonquery is XPath query package for JSON document depended on xpath package, writing in go.

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 - XPath query package for HTML document

  • xmlquery - XPath query package for XML document.

Install Package
go get github.com/antchfx/jsonquery

Get Started

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

Using an xpath like syntax to access specific fields of a json structure.

// https://go.dev/play/p/vqoD_jWryKY
package main

import (
	"fmt"
	"strings"

	"github.com/antchfx/jsonquery"
)

func main() {
	s := `{
            "person":{
               "name":"John",
               "age":31,
               "female":false,
               "city":null,
               "hobbies":[
                  "coding",
                  "eating",
                  "football"
               ]
            }
         }`
	doc, err := jsonquery.Parse(strings.NewReader(s))
	if err != nil {
		panic(err)
	}
	// xpath query
	age := jsonquery.FindOne(doc, "age")
	// or
	age = jsonquery.FindOne(doc, "person/age")
	fmt.Printf("%#v[%T]\n", age.Value(), age.Value()) // prints 31[float64]

	hobbies := jsonquery.FindOne(doc, "//hobbies")
	fmt.Printf("%#v\n", hobbies.Value()) // prints []interface {}{"coding", "eating", "football"}
	firstHobby := jsonquery.FindOne(doc, "//hobbies/*[1]")
	fmt.Printf("%#v\n", firstHobby.Value()) // "coding"
}

Iterating over a json structure.

// https://go.dev/play/p/vwXQKTCLdVK
package main

import (
	"fmt"
	"strings"

	"github.com/antchfx/jsonquery"
)

func main() {
	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())
	}
}

Output:

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

The default Json types and Go types are:

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.
doc, err := jsonquery.LoadURL("http://www.example.com/feed?json")
Load JSON from string.
s :=`{
    "name":"John",
    "age":31,
    "city":"New York"
    }`
doc, err := jsonquery.Parse(strings.NewReader(s))
Load JSON from io.Reader.
f, err := os.Open("./books.json")
doc, err := jsonquery.Parse(f)
Parse JSON array
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 file
s := `[{"name":"John", "age":31, "female":false, "city":null}]`
doc, _ := jsonquery.Parse(strings.NewReader(s))
fmt.Println(doc.OutputXML())
Methods
FindOne()
n := jsonquery.FindOne(doc,"//a")
Find()
list := jsonquery.Find(doc,"//a")
QuerySelector()
n := jsonquery.QuerySelector(doc, xpath.MustCompile("//a"))
QuerySelectorAll()
list :=jsonquery.QuerySelectorAll(doc, xpath.MustCompile("//a"))
Query()
n, err := jsonquery.Query(doc, "*")
QueryAll()
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.

Example of how to convert JSON object to XML file

{
  "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
}
doc, err := jsonquery.Parse(strings.NewReader(s))
if err != nil {
	panic(err)
}
fmt.Println(doc.OutputXML())

Output the below XML:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <expensive>10</expensive>
  <store>
    <bicycle>
      <color>red</color>
      <price>19.95</price>
    </bicycle>
    <book>
      <author>Nigel Rees</author>
      <category>reference</category>
      <id>1</id>
      <price>8.95</price>
      <title>Sayings of the Century</title>
    </book>
    <book>
      <author>Evelyn Waugh</author>
      <category>fiction</category>
      <id>2</id>
      <price>12.99</price>
      <title>Sword of Honour</title>
    </book>
    <book>
      <author>Herman Melville</author>
      <category>fiction</category>
      <id>3</id>
      <isbn>0-553-21311-3</isbn>
      <price>8.99</price>
      <title>Moby Dick</title>
    </book>
    <book>
      <author>J. R. R. Tolkien</author>
      <category>fiction</category>
      <id>4</id>
      <isbn>0-395-19395-8</isbn>
      <price>22.99</price>
      <title>The Lord of the Rings</title>
    </book>
  </store>
</root>

XPath 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 [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/*[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 map[string]interface{} {"id":3,"isbn":"0-553-21311-3",...}
//bicycle 1 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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DisableSelectorCache = false

DisableSelectorCache will disable caching for the query selector if value is true.

View Source
var SelectorCacheMaxEntries = 50

SelectorCacheMaxEntries allows how many selector object can be caching. Default is 50. Will disable caching if SelectorCacheMaxEntries <= 0.

Functions

This section is empty.

Types

type Node

type Node struct {
	Parent, PrevSibling, NextSibling, FirstChild, LastChild *Node

	Type NodeType
	Data string
	// contains filtered or unexported fields
}

A Node consists of a NodeType and some Data (tag name for element nodes, content for text) and are part of a tree of Nodes.

func Find

func Find(top *Node, expr string) []*Node

Find is like QueryAll but will panics if `expr` cannot be parsed.

func FindOne

func FindOne(top *Node, expr string) *Node

FindOne is like Query but will panics if `expr` cannot be parsed.

func LoadURL

func LoadURL(url string) (*Node, error)

LoadURL loads the JSON document from the specified URL.

func Parse

func Parse(r io.Reader) (*Node, error)

Parse JSON document.

func Query

func Query(top *Node, expr string) (*Node, error)

Query searches the Node that matches by the specified XPath expr, and returns first element of matched.

func QueryAll

func QueryAll(top *Node, expr string) ([]*Node, error)

QueryAll searches the Node that matches by the specified XPath expr. Return an error if the expression `expr` cannot be parsed.

func QuerySelector

func QuerySelector(top *Node, selector *xpath.Expr) *Node

QuerySelector returns the first matched XML Node by the specified XPath selector.

func QuerySelectorAll

func QuerySelectorAll(top *Node, selector *xpath.Expr) []*Node

QuerySelectorAll searches all of the Node that matches the specified XPath selectors.

func (*Node) ChildNodes

func (n *Node) ChildNodes() []*Node

ChildNodes gets all child nodes of the node.

func (*Node) InnerText deprecated

func (n *Node) InnerText() string

InnerText will gets the value of the node and all its child nodes.

Deprecated: Use Value() to get JSON object value.

func (*Node) OutputXML added in v1.1.4

func (n *Node) OutputXML() string

OutputXML prints the XML string.

func (*Node) SelectElement

func (n *Node) SelectElement(name string) *Node

SelectElement finds the first of child elements with the specified name.

func (*Node) Value added in v1.3.0

func (n *Node) Value() interface{}

Gets the JSON object value.

type NodeNavigator

type NodeNavigator struct {
	// contains filtered or unexported fields
}

NodeNavigator is for navigating JSON document.

func CreateXPathNavigator

func CreateXPathNavigator(top *Node) *NodeNavigator

CreateXPathNavigator creates a new xpath.NodeNavigator for the specified html.Node.

func (*NodeNavigator) Copy

func (a *NodeNavigator) Copy() xpath.NodeNavigator

func (*NodeNavigator) Current

func (a *NodeNavigator) Current() *Node

func (*NodeNavigator) GetValue added in v1.3.0

func (a *NodeNavigator) GetValue() interface{}

func (*NodeNavigator) LocalName

func (a *NodeNavigator) LocalName() string

func (*NodeNavigator) MoveTo

func (a *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool

func (*NodeNavigator) MoveToChild

func (a *NodeNavigator) MoveToChild() bool

func (*NodeNavigator) MoveToFirst

func (a *NodeNavigator) MoveToFirst() bool

func (*NodeNavigator) MoveToNext

func (a *NodeNavigator) MoveToNext() bool

func (*NodeNavigator) MoveToNextAttribute

func (x *NodeNavigator) MoveToNextAttribute() bool

func (*NodeNavigator) MoveToParent

func (a *NodeNavigator) MoveToParent() bool

func (*NodeNavigator) MoveToPrevious

func (a *NodeNavigator) MoveToPrevious() bool

func (*NodeNavigator) MoveToRoot

func (a *NodeNavigator) MoveToRoot()

func (*NodeNavigator) NodeType

func (a *NodeNavigator) NodeType() xpath.NodeType

func (*NodeNavigator) Prefix

func (a *NodeNavigator) Prefix() string

func (*NodeNavigator) String

func (a *NodeNavigator) String() string

func (*NodeNavigator) Value

func (a *NodeNavigator) Value() string

type NodeType

type NodeType uint

A NodeType is the type of a Node.

const (
	// DocumentNode is a document object that, as the root of the document tree,
	// provides access to the entire XML document.
	DocumentNode NodeType = iota
	// ElementNode is an element.
	ElementNode
	// TextNode is the text content of a node.
	TextNode
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL