Пакет jsontext
Обзор
Пакет jsontext реализует синтаксическую обработку JSON согласно RFC 4627, RFC 7159, RFC 7493, RFC 8259 и RFC 8785. JSON — это простой формат обмена данными, который может представлять примитивные типы данных, такие как логические значения, строки и числа, а также структурированные типы данных, такие как объекты и массивы.
Типы Encoder и Decoder используются для кодирования и декодирования потока токенов или значений JSON.
Токены и значения
Токен JSON обозначает базовые структурные элементы JSON:
- литерал JSON (например, null, true или false)
- строку JSON (например, "hello, world!")
- число JSON (например, 123.456)
- открывающий или закрывающий разделитель объекта JSON (то есть '{' или '}')
- открывающий или закрывающий разделитель массива JSON (то есть '[' или ']')
В Go токен JSON представлен типом Token. Технически существуют ещё два структурных символа (то есть ':' и ','), но для них нет представления типа Token, поскольку их наличие можно вывести из самой структуры грамматики JSON. Например, между именем и значением члена объекта JSON всегда должно подразумеваться двоеточие.
Значение JSON обозначает завершённую единицу данных JSON:
- литерал, строку или число JSON
- объект JSON (например, `{"name":"value"}`)
- массив JSON (например, `[1,2,3]`)
В Go значение JSON представлено типом Value и является []byte, содержащим исходное текстовое представление значения. Понятия токена и значения частично пересекаются, поскольку оба включают литералы, строки и числа. Однако только значение может представлять целый объект или массив JSON.
Типы Encoder и Decoder содержат методы для чтения или записи следующего Token или Value в последовательности. Они поддерживают конечный автомат, проверяющий, образует ли последовательность токенов и/или значений JSON допустимый JSON. Для настройки поведения кодирования и декодирования в конструкторы NewEncoder или NewDecoder можно передать параметры Options.
Терминология
Термины "encode" и "decode" используются для синтаксических функций, связанных с обработкой JSON на основе его грамматики, а термины "marshal" и "unmarshal" — для семантических функций, определяющих смысл значений JSON как значений Go и наоборот. Этот пакет работает с синтаксисом JSON, тогда как encoding/json/v2 работает с семантикой JSON. Цель состоит в том, чтобы чётко различать функции, связанные исключительно с кодированием, и функции маршалинга. Например, можно напрямую закодировать поток токенов JSON, не выполняя маршалинг конкретного значения Go, которое их представляет. Аналогично, можно декодировать поток токенов JSON, не выполняя их анмаршалинг в конкретное значение Go.
При обсуждении JSON в этом пакете используется терминология JSON, которая может отличаться от связанных понятий в Go или в других источниках по вычислительной технике.
- JSON "объект" обозначает неупорядоченную коллекцию членов «имя/значение».
- JSON "массив" обозначает упорядоченную последовательность элементов.
- JSON "значение" обозначает литерал (то есть null, false или true), строку, число, объект или массив.
Дополнительные сведения см. в RFC 8259.
Спецификации
К соответствующим спецификациям относятся RFC 4627, RFC 7159, RFC 7493, RFC 8259 и RFC 8785. Каждый RFC, как правило, является более строгим подмножеством другого RFC. В порядке возрастания строгости:
- RFC 4627 и RFC 7159 не требуют (но рекомендуют) использовать UTF-8, а также не требуют (но рекомендуют), чтобы имена объектов были уникальными.
- RFC 8259 требует использовать UTF-8, но не требует (а рекомендует), чтобы имена объектов были уникальными.
- RFC 7493 требует использовать UTF-8, а также требует, чтобы имена объектов были уникальными.
- RFC 8785 определяет каноническое представление. Он требует использовать UTF-8, а также требует, чтобы имена объектов были уникальными и следовали определённому порядку. В нём точно указано, как должны форматироваться строки и числа.
Основное различие между RFC 4627 и RFC 7159 заключается в том, что первый ограничивал значения верхнего уровня только объектами и массивами JSON, тогда как RFC 7159 и последующие RFC также допускают в качестве значений верхнего уровня null, логические значения, строки или числа JSON.
По умолчанию этот пакет работает в соответствии с RFC 7493, но его можно настроить для работы согласно другим спецификациям RFC. RFC 7493 является более строгим подмножеством RFC 8259 и полностью ему соответствует. В частности, он задаёт конкретное поведение для случаев, оставленных в RFC 8259 неопределёнными, чтобы обеспечить более высокую совместимость.
Вопросы безопасности
См. раздел "Security Considerations" в encoding/json/v2.
Пример (StringReplace)
В этом примере показано использование [Encoder] и [Decoder] для разбора и изменения JSON без его анмаршалинга в конкретный тип Go.
Код:
// Example input with non-idiomatic use of "Golang" instead of "Go".
const input = `{
"title": "Golang version 1 is released",
"author": "Andrew Gerrand",
"date": "2012-03-28",
"text": "Today marks a major milestone in the development of the Golang programming language.",
"otherArticles": [
"Twelve Years of Golang",
"The Laws of Reflection",
"Learn Golang from your browser"
]
}`
// Using a Decoder and Encoder, we can parse through every token,
// check and modify the token if necessary, and
// write the token to the output.
var replacements []jsontext.Pointer
in := strings.NewReader(input)
dec := jsontext.NewDecoder(in)
out := new(bytes.Buffer)
enc := jsontext.NewEncoder(out, jsontext.Multiline(true)) // expand for readability
for {
// Read a token from the input.
tok, err := dec.ReadToken()
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
// Check whether the token contains the string "Golang" and
// replace each occurrence with "Go" instead.
if tok.Kind() == '"' && strings.Contains(tok.String(), "Golang") {
replacements = append(replacements, dec.StackPointer())
tok = jsontext.String(strings.ReplaceAll(tok.String(), "Golang", "Go"))
}
// Write the (possibly modified) token to the output.
if err := enc.WriteToken(tok); err != nil {
log.Fatal(err)
}
}
// Print the list of replacements and the adjusted JSON output.
if len(replacements) > 0 {
fmt.Println(`Replaced "Golang" with "Go" in:`)
for _, where := range replacements {
fmt.Println("\t" + where)
}
fmt.Println()
}
fmt.Println("Result:", out.String())
Результат:
Replaced "Golang" with "Go" in:
/title
/text
/otherArticles/0
/otherArticles/2
Result: {
"title": "Go version 1 is released",
"author": "Andrew Gerrand",
"date": "2012-03-28",
"text": "Today marks a major milestone in the development of the Go programming language.",
"otherArticles": [
"Twelve Years of Go",
"The Laws of Reflection",
"Learn Go from your browser"
]
}
Указатель
Файлы пакета
decode.go doc.go encode.go errors.go export.go options.go pools.go quote.go state.go token.go value.go
Переменные
ErrDuplicateName указывает, что токен JSON не удалось закодировать или декодировать, поскольку это приводит к дублированию имени объекта JSON. При возникновении эта ошибка непосредственно оборачивается в SyntacticError.
Имя дублирующегося члена объекта JSON можно извлечь следующим образом:
err := ...
serr, ok := errors.AsType[*jsontext.SyntacticError](err)
if ok && serr.Err == jsontext.ErrDuplicateName {
ptr := serr.JSONPointer // JSON pointer to duplicate name
name := ptr.LastToken() // duplicate name itself
...
}
Эта ошибка возвращается только в том случае, если AllowDuplicateNames имеет значение false.
var ErrDuplicateName = errors.New("duplicate object member name") ErrNonStringName указывает, что токен JSON не удалось закодировать или декодировать, поскольку он не является строкой, как того требует RFC 8259, раздел 4, для имён объектов JSON. При возникновении эта ошибка непосредственно оборачивается в SyntacticError.
var ErrNonStringName = errors.New("object member name must be a string") Internal предназначена только для внутреннего использования. На неё не распространяется соглашение о совместимости Go.
var Internal exporter
func AppendFloat 1.27
func AppendFloat(dst []byte, src float64, bits int) []byte
AppendFloat добавляет src к dst в виде числа JSON согласно RFC 8259, раздел 6.
За исключением -0, который форматируется как -0, а не 0, результат идентичен ECMA-262, 10-е издание, раздел 7.1.12.1, и (для точности 64 бита) RFC 8785, раздел 3.2.2.3. Значения NaN, +Inf и -Inf будут представлены в виде строк JSON со значениями "NaN", "Infinity" и "-Infinity".
Обратите внимание, что большинство библиотек и стандартов JSON предполагают, что числа JSON являются числами с плавающей точкой двойной точности (64 бита). Поэтому предпочтительно использовать точность 64 бита, если только получатель не может узнать из другого контекста, что закодированное число имеет точность 32 бита.
func AppendFormat 1.27
func AppendFormat[Bytes ~[]byte | ~string](dst []byte, src Bytes, opts ...Options) ([]byte, error)
AppendFormat форматирует значение JSON в src согласно указанным параметрам и добавляет его к dst. Подробнее о форматировании см. в описании Value.Format.
Области памяти dst и src могут перекрываться. Если сообщается об ошибке, к dst добавляется содержимое src целиком.
func AppendQuote 1.27
func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error)
AppendQuote добавляет к dst строковый литерал JSON в двойных кавычках, представляющий src, и возвращает расширенный буфер. Используется минимальное представление строки согласно RFC 8785, раздел 3.2.2.2. Недопустимые байты UTF-8 заменяются символом замены Unicode, а в конце возвращается ошибка, указывающая на наличие недопустимого UTF-8. Области памяти dst и src не должны перекрываться.
func AppendUnquote 1.27
func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error)
AppendUnquote добавляет к dst декодированное представление src как строкового литерала JSON в двойных кавычках и возвращает расширенный буфер. Входные данные src должны быть строкой JSON без окружающих пробелов. Недопустимые байты UTF-8 заменяются символом замены Unicode, а в конце возвращается ошибка, указывающая на наличие недопустимого UTF-8. Любые байты после строкового литерала JSON приводят к ошибке. Области памяти dst и src не должны перекрываться.
type Decoder 1.27
Decoder — это потоковый декодер необработанных токенов и значений JSON. Он используется для чтения потока значений JSON верхнего уровня, разделённых необязательными пробельными символами.
Вызовы Decoder.ReadToken и Decoder.ReadValue можно чередовать. Например, следующее значение JSON:
{"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}}
можно разобрать с помощью следующих вызовов (для краткости ошибки игнорируются):
d.ReadToken() // {
d.ReadToken() // "name"
d.ReadToken() // "value"
d.ReadValue() // "array"
d.ReadToken() // [
d.ReadToken() // null
d.ReadToken() // false
d.ReadValue() // true
d.ReadToken() // 3.14159
d.ReadToken() // ]
d.ReadValue() // "object"
d.ReadValue() // {"k":"v"}
d.ReadToken() // }
Это лишь одна из многих возможных последовательностей вызовов, и она может быть не самым разумным способом обработки конкретного токена или значения. Например, для получения строкового токена имени объекта чаще вызывают Decoder.ReadToken.
type Decoder struct {
// contains filtered or unexported fields
}
func NewDecoder 1.27
func NewDecoder(r io.Reader, opts ...Options) *Decoder
NewDecoder создаёт новый потоковый декодер, читающий данные из r.
Если r — это bytes.Buffer, декодер разбирает данные непосредственно из буфера, не копируя предварительно его содержимое во временный буфер. Во время работы декодера в буфер нельзя записывать дополнительные данные.
func (*Decoder) InputOffset 1.27
func (d *Decoder) InputOffset() int64
InputOffset возвращает текущее смещение во входных байтах. Оно указывает на следующий байт сразу после последнего возвращённого токена или значения. Из-за внутренней буферизации количество байтов, фактически прочитанных из базового io.Reader, может превышать это смещение.
func (*Decoder) Options 1.27
func (d *Decoder) Options() Options
Options возвращает параметры, использованные для создания декодера; кроме того, они могут содержать семантические параметры, переданные вызову encoding/json/v2.UnmarshalDecode.
Если метод выполняется внутри вызова encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom или функции encoding/json/v2.UnmarshalFromFunc, возвращённые параметры действительны только в пределах этого вызова.
func (*Decoder) PeekKind 1.27
func (d *Decoder) PeekKind() Kind
PeekKind получает тип следующего токена, не сдвигая смещение чтения.
При возникновении ошибки возвращается KindInvalid. Такая ошибка кэшируется до следующего вызова чтения; вызывающая сторона должна впоследствии выполнить вызов чтения после вызова PeekKind.
func (*Decoder) ReadToken 1.27
func (d *Decoder) ReadToken() (Token, error)
ReadToken читает следующий Token, сдвигая смещение чтения. Возвращённый токен действителен только до следующего вызова Peek, Read или Skip. Если токенов больше нет, возвращается io.EOF.
func (*Decoder) ReadValue 1.27
func (d *Decoder) ReadValue() (Value, error)
ReadValue возвращает следующее необработанное значение JSON, сдвигая смещение чтения. Из значения удаляются начальные и конечные пробелы; оно содержит точные байты входных данных, которые могут включать недопустимый UTF-8, если указан параметр AllowInvalidUTF8.
Возвращённое значение действительно только до следующего вызова Peek, Read или Skip; его нельзя изменять, пока используется Decoder. Если декодер находится на закрывающем токене объекта или массива, возвращается SyntacticError, а внутреннее состояние не меняется. Если значений больше нет, возвращается io.EOF.
func (*Decoder) Reset 1.27
func (d *Decoder) Reset(r io.Reader, opts ...Options)
Reset сбрасывает декодер, чтобы он заново считывал данные из r и был настроен с указанными параметрами. Нельзя вызывать Reset для Decoder, переданного методу encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom или функции encoding/json/v2.UnmarshalFromFunc.
func (*Decoder) SkipValue 1.27
func (d *Decoder) SkipValue() error
По семантике SkipValue эквивалентен вызову Decoder.ReadValue с отбрасыванием результата, однако память не расходуется впустую на хранение результата целиком.
func (*Decoder) StackDepth 1.27
func (d *Decoder) StackDepth() int
StackDepth возвращает глубину конечного автомата для уже прочитанных данных JSON. Каждый уровень стека соответствует вложенному объекту или массиву JSON. Глубина увеличивается при обнаружении токена BeginObject или BeginArray и уменьшается при обнаружении токена EndObject или EndArray.
StackDepth возвращает 0, если текущая позиция находится вне объектов и массивов. В частности, он возвращает 0 до чтения любых токенов, после чтения любого значения верхнего уровня и между значениями при декодировании потока значений верхнего уровня (например, NDJSON). StackDepth возвращает 1 внутри объекта или массива верхнего уровня, 2 внутри вложенного объекта или массива и так далее.
Например, рассмотрим декодирование следующего JSON:
{"a": [1, 2], "b": {"c": 3}}
Во время декодирования StackDepth возвращал бы следующие значения:
- В начале StackDepth возвращает 0.
- После декодирования внешнего '{' StackDepth возвращает 1.
- После декодирования внутреннего '[' StackDepth возвращает 2.
- После декодирования внутреннего ']' StackDepth возвращает 1.
- После декодирования внешнего '}' StackDepth возвращает 0.
func (*Decoder) StackIndex 1.27
func (d *Decoder) StackIndex(i int) (Kind, int64)
StackIndex возвращает сведения об указанном уровне стека. Значение должно находиться в диапазоне от 0 до Decoder.StackDepth включительно. Для каждого уровня возвращается его тип:
- KindInvalid для уровня 0,
- KindBeginObject для уровня, представляющего объект JSON, и
- KindBeginArray для уровня, представляющего массив JSON.
Также возвращается длина уже декодированной части этого объекта или массива JSON. Имя и значение в объекте JSON подсчитываются отдельно, поэтому фактическое количество членов равно половине длины. Длина полного объекта JSON должна быть чётной.
func (*Decoder) StackPointer 1.27
func (d *Decoder) StackPointer() Pointer
StackPointer возвращает JSON Pointer (RFC 6901) к последнему прочитанному значению.
func (*Decoder) UnreadBuffer 1.27
func (d *Decoder) UnreadBuffer() []byte
UnreadBuffer возвращает данные, оставшиеся в буфере непрочитанных данных; он может содержать ноль или более байтов. Это данные, уже полученные из входного io.Reader, но ещё не прочитанные вызовом Decoder.ReadToken или Decoder.ReadValue. Они могут содержать байты, не образующие допустимый JSON, поскольку ещё не проверялись по грамматике JSON. Точный объём буферизованных данных является деталью реализации Decoder и может меняться со временем.
Вызывающая сторона отвечает за объединение этого буфера с оставшейся частью входного Reader, чтобы получить полную последовательность байтов после последнего прочитанного токена или значения JSON.
Нельзя изменять возвращённый буфер, пока используется Decoder. Содержимое буфера действительно до следующего вызова Peek, Read или Skip.
type Encoder 1.27
Encoder — это потоковый кодировщик необработанных токенов и значений JSON. Он используется для записи потока значений JSON верхнего уровня, каждое из которых завершается символом новой строки.
Вызовы Encoder.WriteToken и Encoder.WriteValue можно чередовать. Например, следующее значение JSON:
{"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}}
можно сформировать с помощью следующих вызовов (для краткости ошибки игнорируются):
e.WriteToken(BeginObject) // {
e.WriteToken(String("name")) // "name"
e.WriteToken(String("value")) // "value"
e.WriteValue(Value(`"array"`)) // "array"
e.WriteToken(BeginArray) // [
e.WriteToken(Null) // null
e.WriteToken(False) // false
e.WriteValue(Value("true")) // true
e.WriteToken(Float(3.14159)) // 3.14159
e.WriteToken(EndArray) // ]
e.WriteValue(Value(`"object"`)) // "object"
e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"}
e.WriteToken(EndObject) // }
Это лишь одна из многих возможных последовательностей вызовов, и она может быть не самым разумным способом обработки конкретного токена или значения. Например, для имён объектов чаще вызывают Encoder.WriteToken, передавая ему строку.
type Encoder struct {
// contains filtered or unexported fields
}
func NewEncoder 1.27
func NewEncoder(w io.Writer, opts ...Options) *Encoder
NewEncoder создаёт новый потоковый кодировщик, записывающий данные в w и настроенный с указанными параметрами. Он сбрасывает внутренний буфер, когда тот достаточно заполняется или когда записано значение верхнего уровня.
Если w — это bytes.Buffer, кодировщик добавляет данные непосредственно в буфер, не копируя содержимое из промежуточного буфера.
func (*Encoder) AvailableBuffer 1.27
func (e *Encoder) AvailableBuffer() []byte
AvailableBuffer возвращает буфер нулевой длины, ёмкость которого может быть ненулевой. Этот буфер предназначен для заполнения значением Value, передаваемым в непосредственно следующий вызов Encoder.WriteValue.
Пример использования:
b := e.AvailableBuffer() b = append(b, '"') b = appendString(b, v) // append the string formatting of v b = append(b, '"') ... := e.WriteValue(b)
Обратите внимание, что WriteValue ожидает допустимое значение JSON. Создание значения в виде необработанного []byte требует большей осторожности, чем использование функций-конструкторов, таких как String, которые всегда возвращают допустимые [Token] или [Value].
func (*Encoder) Options 1.27
func (e *Encoder) Options() Options
Options возвращает параметры, использованные для создания кодировщика; кроме того, они могут содержать семантические параметры, переданные вызову encoding/json/v2.MarshalEncode.
Если метод выполняется внутри вызова encoding/json/v2.MarshalerTo.MarshalJSONTo или функции encoding/json/v2.MarshalToFunc, возвращённые параметры действительны только в пределах этого вызова.
func (*Encoder) OutputOffset 1.27
func (e *Encoder) OutputOffset() int64
OutputOffset возвращает текущее смещение в выходных байтах. Оно указывает на следующий байт сразу после последнего записанного токена или значения. Из-за внутренней буферизации количество байтов, фактически записанных в базовый io.Writer, может быть меньше этого смещения.
func (*Encoder) Reset 1.27
func (e *Encoder) Reset(w io.Writer, opts ...Options)
Reset сбрасывает кодировщик, чтобы он заново записывал данные в w и был настроен с указанными параметрами. Нельзя вызывать Reset для Encoder, переданного методу encoding/json/v2.MarshalerTo.MarshalJSONTo или функции encoding/json/v2.MarshalToFunc.
func (*Encoder) StackDepth 1.27
func (e *Encoder) StackDepth() int
StackDepth возвращает глубину конечного автомата для записанных данных JSON. Каждый уровень стека соответствует вложенному объекту или массиву JSON. Глубина увеличивается при обнаружении токена BeginObject или BeginArray и уменьшается при обнаружении токена EndObject или EndArray.
StackDepth возвращает 0, если текущая позиция находится вне объектов и массивов. В частности, он возвращает 0 до записи любых токенов, после записи любого значения верхнего уровня и между значениями при кодировании потока значений верхнего уровня (например, NDJSON). StackDepth возвращает 1 внутри объекта или массива верхнего уровня, 2 внутри вложенного объекта или массива и так далее.
Например, рассмотрим кодирование следующего JSON:
{"a": [1, 2], "b": {"c": 3}}
Во время кодирования StackDepth возвращал бы следующие значения:
- В начале StackDepth возвращает 0.
- После кодирования внешнего '{' StackDepth возвращает 1.
- После кодирования внутреннего '[' StackDepth возвращает 2.
- После кодирования внутреннего ']' StackDepth возвращает 1.
- После кодирования внешнего '}' StackDepth возвращает 0.
func (*Encoder) StackIndex 1.27
func (e *Encoder) StackIndex(i int) (Kind, int64)
StackIndex возвращает сведения об указанном уровне стека. Значение должно находиться в диапазоне от 0 до Encoder.StackDepth включительно. Для каждого уровня возвращается его тип:
- KindInvalid для уровня 0,
- KindBeginObject для уровня, представляющего объект JSON, и
- KindBeginArray для уровня, представляющего массив JSON.
Также возвращается длина уже закодированной части этого объекта или массива JSON. Имя и значение в объекте JSON подсчитываются отдельно, поэтому фактическое количество членов равно половине длины. Длина полного объекта JSON должна быть чётной.
func (*Encoder) StackPointer 1.27
func (e *Encoder) StackPointer() Pointer
StackPointer возвращает JSON Pointer (RFC 6901) к последнему записанному значению.
func (*Encoder) WriteToken 1.27
func (e *Encoder) WriteToken(t Token) error
WriteToken записывает следующий токен и сдвигает внутреннее смещение записи.
Тип переданного токена должен соответствовать грамматике JSON. Например, ошибкой будет передать число, когда кодировщик ожидает имя объекта (которое всегда является строкой), или передать закрывающий разделитель объекта, когда кодировщик завершает массив. Если переданный токен недопустим, WriteToken возвращает SyntacticError, а внутреннее состояние не меняется. Смещение, указанное в SyntacticError, будет равно Encoder.OutputOffset плюс количество разделителей или пробельных символов, которые предшествовали бы переданному токену.
func (*Encoder) WriteValue 1.27
func (e *Encoder) WriteValue(v Value) error
WriteValue записывает следующее необработанное значение и сдвигает внутреннее смещение записи. Encoder не просто копирует переданное значение без изменений, а разбирает его, чтобы убедиться в его синтаксической корректности, и форматирует согласно настройкам форматирования пробелов и строк Encoder. Если указан параметр AllowInvalidUTF8, любой недопустимый UTF-8 преобразуется в символ замены Unicode U+FFFD.
Тип переданного значения должен соответствовать грамматике JSON (см. примеры в описании Encoder.WriteToken). Если переданное значение недопустимо, WriteValue возвращает SyntacticError, а внутреннее состояние не меняется. Смещение, указанное в SyntacticError, будет равно Encoder.OutputOffset плюс смещение в v, на котором обнаружена синтаксическая ошибка.
type Kind 1.27
Kind представляет тип токена JSON.
Kind — это один байт, который удобно совпадает с первым байтом символа этого типа в грамматике (за исключением чисел, которые всегда представлены символом '0').
type Kind byte
const (
KindInvalid Kind = 0 // invalid kind
KindNull Kind = 'n' // null
KindFalse Kind = 'f' // false
KindTrue Kind = 't' // true
KindString Kind = '"' // string
KindNumber Kind = '0' // number
KindBeginObject Kind = '{' // begin object
KindEndObject Kind = '}' // end object
KindBeginArray Kind = '[' // begin array
KindEndArray Kind = ']' // end array
) func (Kind) String 1.27
func (k Kind) String() string
String возвращает строковое представление k.
type Options 1.27
Options настраивает NewEncoder, Encoder.Reset, NewDecoder и Decoder.Reset, задавая определённые возможности. Каждая функция принимает переменное число параметров options; свойства, заданные в более поздних параметрах, переопределяют значения свойств, заданных ранее.
Существует один тип Options, используемый как для кодирования, так и для декодирования. Некоторые параметры влияют на обе операции, а другие — только на одну:
- AllowDuplicateNames влияет на кодирование и декодирование
- AllowInvalidUTF8 влияет на кодирование и декодирование
- EscapeForHTML влияет только на кодирование
- EscapeForJS влияет только на кодирование
- PreserveRawStrings влияет только на кодирование
- CanonicalizeRawInts влияет только на кодирование
- CanonicalizeRawFloats влияет только на кодирование
- ReorderRawObjects влияет только на кодирование
- SpaceAfterColon влияет только на кодирование
- SpaceAfterComma влияет только на кодирование
- Multiline влияет только на кодирование
- WithIndent влияет только на кодирование
- WithIndentPrefix влияет только на кодирование
Параметры, не влияющие на конкретную операцию, игнорируются.
Тип Options идентичен encoding/json.Options и encoding/json/v2.Options. Параметры из других пакетов можно передавать функциям этого пакета, но они будут проигнорированы. Параметры из этого пакета можно использовать с другими пакетами.
type Options = jsonopts.Options
func AllowDuplicateNames 1.27
func AllowDuplicateNames(v bool) Options
AllowDuplicateNames указывает, что объекты JSON могут содержать повторяющиеся имена элементов. Отключение проверки на повторяющиеся имена может повысить производительность, но нарушает соответствие разделу 2.3 RFC 7493. Входные и выходные данные по-прежнему будут соответствовать RFC 8259, в котором обработка повторяющихся имён оставлена неопределённой.
Влияет как на кодирование, так и на декодирование.
func AllowInvalidUTF8 1.27
func AllowInvalidUTF8(v bool) Options
AllowInvalidUTF8 указывает, что строки JSON могут содержать некорректный UTF-8, который будет искажён и заменён символом замены Unicode U+FFFD. Это приводит к нарушению кодировщиком или декодировщиком требований раздела 2.1 RFC 7493 и раздела 8.1 RFC 8259.
Влияет как на кодирование, так и на декодирование.
func CanonicalizeRawFloats 1.27
func CanonicalizeRawFloats(v bool) Options
CanonicalizeRawFloats указывает, что при кодировании числа с плавающей точкой JSON в исходном виде (то есть числа с дробной частью или экспонентой) в Token или Value это число канонизируется согласно разделу 3.2.2.3 RFC 8785. В особом случае число -0 канонизируется как 0.
Числа JSON рассматриваются как числа двойной точности IEEE 754. Безопасно канонизировать сериализованное число одинарной точности, а затем разбирать его обратно как число одинарной точности, ожидая получить то же значение. Если число превышает ±1.7976931348623157e+308 — максимальное конечное значение, — оно ограничивается этим значением и форматируется соответствующим образом.
Влияет только на кодирование и игнорируется при декодировании.
func CanonicalizeRawInts 1.27
func CanonicalizeRawInts(v bool) Options
CanonicalizeRawInts указывает, что при кодировании целого числа JSON в исходном виде (то есть числа без дробной части и экспоненты) в Token или Value это число канонизируется согласно разделу 3.2.2.3 RFC 8785. В особом случае число -0 канонизируется как 0.
Числа JSON рассматриваются как числа двойной точности IEEE 754. Любые числа, точность которых превышает возможности такого представления, потеряют точность при канонизации. Например, целые числа за пределами ±2⁵³ потеряют точность. Так, 1234567890123456789 форматируется как 1234567890123456800.
Влияет только на кодирование и игнорируется при декодировании.
func EscapeForHTML 1.27
func EscapeForHTML(v bool) Options
EscapeForHTML указывает, что символы '<', '>' и '&' в строках JSON следует экранировать в виде шестнадцатеричного кода Unicode (например, \u003c), чтобы результат можно было безопасно встраивать в HTML.
Влияет только на кодирование и игнорируется при декодировании.
Пример
Для безопасного встраивания JSON непосредственно в HTML требуется специальная обработка. Экранируйте некоторые руны, чтобы предотвратить внедрение <script> при непосредственной интерпретации JSON как HTML. В этом примере показано, как добиться поведения, эквивалентного поведению пакета v1 [encoding/json], поддержка которого в этом пакете больше не предоставляется напрямую. В новом коде, где JSON смешивается с HTML, для обеспечения безопасности следует использовать модуль [github.com/google/safehtml].
Код:
page := struct {
Title string
Body string
}{
Title: "Example Embedded Javascript",
Body: `<script> console.log("Hello, world!"); </script>`,
}
b, err := json.Marshal(&page,
// Escape certain runes within a JSON string so that
// JSON will be safe to directly embed inside HTML.
jsontext.EscapeForHTML(true),
jsontext.EscapeForJS(true),
jsontext.Multiline(true)) // expand for readability
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
Вывод:
{
"Title": "Example Embedded Javascript",
"Body": "\u003cscript\u003e console.log(\"Hello, world!\"); \u003c/script\u003e"
}
func EscapeForJS 1.27
func EscapeForJS(v bool) Options
EscapeForJS указывает, что символы U+2028 и U+2029 в строках JSON следует экранировать в виде шестнадцатеричного кода Unicode (например, \u2028), чтобы результат можно было корректно встраивать в JavaScript. См. раздел 12 RFC 8259.
Влияет только на кодирование и игнорируется при декодировании.
func Multiline 1.27
func Multiline(v bool) Options
Multiline указывает, что вывод JSON должен состоять из нескольких строк: каждый элемент объекта JSON или массива JSON располагается на новой строке с отступом, соответствующим уровню вложенности.
Если SpaceAfterColon не задан, по умолчанию используется значение true. Если SpaceAfterComma не задан, по умолчанию используется значение false. Если WithIndent не задан, по умолчанию используется "\t".
Если задано значение false, вывод будет состоять из одной строки, а единственные пробелы в нём будут определяться текущими значениями SpaceAfterColon и SpaceAfterComma.
Влияет только на кодирование и игнорируется при декодировании.
Пример
Код:
type Pet struct {
Name string
Species string
Breed string
}
p := Pet{
Name: "Oliver",
Species: "Dog",
Breed: "Goldendoodle",
}
b, err := json.Marshal(p, jsontext.Multiline(true))
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
Вывод:
{
"Name": "Oliver",
"Species": "Dog",
"Breed": "Goldendoodle"
}
func PreserveRawStrings 1.27
func PreserveRawStrings(v bool) Options
PreserveRawStrings указывает, что при кодировании строки JSON в исходном виде в Token или Value предварительно экранированные последовательности в строке JSON сохраняются в выводе. При этом для исходных строк по-прежнему учитываются параметры EscapeForHTML и EscapeForJS, то есть соответствующие символы экранируются. Если включён AllowInvalidUTF8, байты некорректного UTF-8 сохраняются в выводе.
Влияет только на кодирование и игнорируется при декодировании.
func ReorderRawObjects 1.27
func ReorderRawObjects(v bool) Options
ReorderRawObjects указывает, что при кодировании объекта JSON в исходном виде в Value элементы объекта переставляются в соответствии с разделом 3.2.3 RFC 8785.
Влияет только на кодирование и игнорируется при декодировании.
func SpaceAfterColon 1.27
func SpaceAfterColon(v bool) Options
SpaceAfterColon указывает, что после каждого разделителя- двоеточия, следующего за именем объекта JSON, в выводе JSON следует добавлять пробел. Если значение равно false, после разделителя-двоеточия пробел не ставится.
Влияет только на кодирование и игнорируется при декодировании.
func SpaceAfterComma 1.27
func SpaceAfterComma(v bool) Options
SpaceAfterComma указывает, что после каждого разделителя-запятой, следующего за значением объекта JSON или элементом массива, в выводе JSON следует добавлять пробел. Если значение равно false, после разделителя-запятой пробел не ставится.
Влияет только на кодирование и игнорируется при декодировании.
func WithIndent 1.27
func WithIndent(indent string) Options
WithIndent указывает, что кодировщик должен формировать многострочный вывод, в котором каждый элемент объекта JSON или массива начинается с новой строки и отступа, состоящего из префикса отступа (см. WithIndentPrefix) и одного или нескольких повторений строки отступа в зависимости от уровня вложенности. Строка отступа может состоять только из пробелов и табуляций.
Если требуется вывод с отступами, но конкретная строка отступа не имеет значения, используйте вместо этого Multiline.
Влияет только на кодирование и игнорируется при декодировании. Использование этого параметра подразумевает, что для Multiline установлено значение true.
func WithIndentPrefix 1.27
func WithIndentPrefix(prefix string) Options
WithIndentPrefix указывает, что кодировщик должен формировать многострочный вывод, в котором каждый элемент объекта JSON или массива начинается с новой строки и отступа, состоящего из префикса отступа и одного или нескольких повторений строки отступа (см. WithIndent) в зависимости от уровня вложенности. Префикс может состоять только из пробелов и табуляций.
Влияет только на кодирование и игнорируется при декодировании. Использование этого параметра подразумевает, что для Multiline установлено значение true.
type Pointer 1.27
Pointer — это указатель JSON (RFC 6901), который ссылается на определённое значение JSON относительно корня значения JSON верхнего уровня.
Pointer представляет собой разделённый косыми чертами список токенов, где каждый токен — это либо имя объекта JSON, либо индекс элемента массива JSON, закодированный в виде целого числа в десятичной системе счисления. Невозможно отличить индекс массива от имени объекта (которое случайно закодировано десятичным целым числом), не зная структуры значения JSON верхнего уровня, на которое ссылается указатель.
Для указателя на определённое значение существует ровно одно представление, поэтому сравнимость значений Pointer эквивалентна проверке того, указывают ли они на одно и то же значение.
type Pointer string
func (Pointer) AppendToken 1.27
func (p Pointer) AppendToken(tok string) Pointer
AppendToken добавляет токен в конец p и возвращает полный указатель.
func (Pointer) Contains 1.27
func (p Pointer) Contains(pc Pointer) bool
Contains сообщает, равно ли значение JSON, на которое указывает p, значению JSON, на которое указывает pc, или содержит ли оно это значение.
func (Pointer) IsValid 1.27
func (p Pointer) IsValid() bool
IsValid сообщает, является ли p допустимым указателем JSON согласно RFC 6901. Обратите внимание, что конкатенация двух допустимых указателей даёт допустимый указатель.
func (Pointer) LastToken 1.27
func (p Pointer) LastToken() string
LastToken возвращает последний токен указателя. Последний токен пустого Pointer — пустая строка.
func (Pointer) Parent 1.27
func (p Pointer) Parent() Pointer
Parent удаляет последний токен и возвращает оставшийся указатель. Родительский указатель для пустого Pointer — пустая строка.
func (Pointer) Tokens 1.27
func (p Pointer) Tokens() iter.Seq[string]
Tokens возвращает итератор по токенам ссылки в указателе JSON, от первого до последнего.
type SyntacticError 1.27
SyntacticError описывает ошибку, возникшую при кодировании или декодировании JSON согласно грамматике.
Содержимое этой ошибки, формируемое данным пакетом, может со временем измениться.
type SyntacticError struct {
// ByteOffset indicates that an error occurred at or after this byte offset.
ByteOffset int64
// JSONPointer indicates that an error occurred within this JSON value
// as indicated using the JSON Pointer notation (see RFC 6901).
JSONPointer Pointer
// Err is the underlying error.
Err error
// contains filtered or unexported fields
}
func (*SyntacticError) Error 1.27
func (e *SyntacticError) Error() string
func (*SyntacticError) Unwrap 1.27
func (e *SyntacticError) Unwrap() error
type Token 1.27
Token представляет лексический токен JSON, который может быть одним из следующих:
- литерал JSON (то есть null, true или false)
- строка JSON (например, "hello, world!")
- число JSON (например, 123.456)
- открывающий или закрывающий разделитель объекта JSON (то есть { или } )
- открывающий или закрывающий разделитель массива JSON (то есть [ или ] )
Token не может представлять значения массивов или объектов целиком, в отличие от Value. Токена для представления запятых и двоеточий нет, поскольку эти структурные токены можно определить по окружающему контексту.
Token хранит данные в одном из двух видов:
В виде исходного текста JSON: данные хранятся во внутреннем буфере Decoder и создаются только методом Decoder.ReadToken. Такой токен действителен только до следующего вызова любого метода этого Decoder (например, Decoder.PeekKind, Decoder.ReadToken, Decoder.ReadValue или Decoder.SkipValue). Вызовите Token.Clone, чтобы скопировать исходный текст в отдельную область памяти, которая сохранится после последующих вызовов Decoder.
В виде типизированного значения Go: автономное представление, создаваемое функциями-конструкторами (например, String, Int, Uint, Float). Такие токены действительны бессрочно, и их не требуется клонировать.
type Token struct {
// contains filtered or unexported fields
}
var (
Null Token = rawToken("null")
False Token = rawToken("false")
True Token = rawToken("true")
BeginObject Token = rawToken("{")
EndObject Token = rawToken("}")
BeginArray Token = rawToken("[")
EndArray Token = rawToken("]")
) func Bool 1.27
func Bool(b bool) Token
Bool создаёт Token, представляющий логическое значение JSON.
func Float 1.27
func Float(n float64) Token
Float создаёт Token, представляющий число JSON в виде числа с плавающей точкой 64-битной точности, форматируемого согласно разделу 7.1.12.1 10-го издания ECMA-262 и разделу 3.2.2.3 RFC 8785, за исключением того, что -0 по-прежнему форматируется как -0. Значения NaN, +Inf и -Inf будут представлены строками JSON со значениями "NaN", "Infinity" и "-Infinity".
func Float32 1.27
func Float32(n float32) Token
Float32 создаёт Token, представляющий число JSON в виде числа с плавающей точкой 32-битной точности, форматируемого согласно разделу 7.1.12.1 10-го издания ECMA-262, за исключением того, что -0 по-прежнему форматируется как -0. Значения NaN, +Inf и -Inf будут представлены строками JSON со значениями "NaN", "Infinity" и "-Infinity".
Обратите внимание, что большинство библиотек и стандартов JSON предполагают, что числа JSON имеют 64-битную точность с плавающей точкой. Точность 32 бита следует использовать только в том случае, если соответствующий декодировщик знает, что этот токен числа JSON должен иметь точность только 32 бита. Во всех остальных случаях предпочтительнее использовать конструктор Float.
func Int 1.27
func Int(n int64) Token
Int создаёт Token, представляющий число JSON на основе int64.
func String 1.27
func String(s string) Token
String создаёт Token, представляющий строку JSON. Переданная строка должна содержать корректный UTF-8, иначе некорректные символы могут быть искажены и заменены символом замены Unicode.
func Uint 1.27
func Uint(n uint64) Token
Uint создаёт Token, представляющий число JSON на основе uint64.
func (Token) Bool 1.27
func (t Token) Bool() bool
Bool возвращает значение логического типа для логического значения JSON. Вызывает панику, если тип токена не является логическим значением JSON.
func (Token) Clone 1.27
func (t Token) Clone() Token
Clone возвращает копию токена со значением, не хранящимся в буфере Decoder, поэтому оно остаётся действительным после последующих вызовов Decoder. Не влияет на токены, созданные функциями-конструкторами, поскольку они уже автономны.
func (Token) Float 1.27
func (t Token) Float() (float64, error)
Float возвращает значение с плавающей точкой для числа JSON, разобранного с точностью 64 бита.
Если число JSON выходит за представимый диапазон float64, возвращается +Inf или -Inf вместе с ошибкой, которая, согласно errors.Is, соответствует strconv.ErrRange.
Для любой строки JSON со значением "NaN", "Infinity" или "-Infinity" возвращается значение NaN, +Inf или -Inf.
Вызывает панику, если тип токена не является числом JSON или строкой JSON с одним из указанных значений.
func (Token) Float32 1.27
func (t Token) Float32() (float32, error)
Float32 возвращает значение с плавающей точкой для числа JSON, разобранного с точностью 32 бита.
Если число JSON выходит за представимый диапазон float32, возвращается +Inf или -Inf вместе с ошибкой, которая, согласно errors.Is, соответствует strconv.ErrRange.
Для любой строки JSON со значением "NaN", "Infinity" или "-Infinity" возвращается значение NaN, +Inf или -Inf.
Вызывает панику, если тип токена не является числом JSON или строкой JSON с одним из указанных значений.
Обратите внимание, что большинство библиотек и стандартов JSON предполагают, что числа JSON имеют 64-битную точность с плавающей точкой. Этот метод следует использовать только в том случае, если вызывающий код знает из другого контекста, что данный токен — это число JSON, отформатированное с точностью только 32 бита (например, созданное с помощью конструктора Float32). Во всех остальных случаях предпочтительнее использовать метод доступа Token.Float.
func (Token) Int 1.27
func (t Token) Int() (int64, error)
Int возвращает целочисленное значение со знаком для числа JSON.
Если число JSON не соответствует ограниченной грамматике целого числа со знаком, возвращается ошибка, которая, согласно errors.Is, соответствует strconv.ErrSyntax. Если число JSON является целым числом со знаком, но выходит за диапазон int64, возвращается ошибка, которая, согласно errors.Is, соответствует strconv.ErrRange. Даже при возникновении ошибки возвращается разумное значение. Дробная часть любого числа игнорируется (усечение к нулю). Числа, выходящие за пределы представления int64, ограничиваются ближайшим представимым значением.
Вызывает панику, если тип токена не является числом JSON.
func (Token) Kind 1.27
func (t Token) Kind() Kind
Kind возвращает тип токена.
func (Token) String 1.27
func (t Token) String() string
String возвращает неэкранированное строковое значение для строки JSON. Для других типов JSON возвращает исходное представление JSON.
func (Token) Uint 1.27
func (t Token) Uint() (uint64, error)
Uint возвращает целочисленное значение без знака для числа JSON.
Если число JSON не соответствует ограниченной грамматике беззнакового целого числа, возвращается ошибка, соответствующая strconv.ErrSyntax. Если число JSON является беззнаковым целым, но выходит за представимый диапазон uint64, возвращается ошибка, соответствующая strconv.ErrRange. Даже при возникновении ошибки возвращается разумное значение. Дробная часть любого числа игнорируется (усечение к нулю). Числа, выходящие за пределы представления uint64, ограничиваются ближайшим представимым значением.
Вызывает панику, если тип токена не является числом JSON.
type Value 1.27
Value представляет одно исходное значение JSON, которое может быть одним из следующих:
- литерал JSON (то есть null, true или false)
- строка JSON (например, "hello, world!")
- число JSON (например, 123.456)
- объект JSON целиком (например, {"fizz":"buzz"} )
- массив JSON целиком (например, [1,2,3] )
Value может представлять значения массивов или объектов целиком, в отличие от Token. Value может содержать начальные и/или конечные пробелы.
type Value []byte
func (*Value) Canonicalize 1.27
func (v *Value) Canonicalize(opts ...Options) error
Canonicalize канонизирует исходное значение JSON согласно схеме канонизации JSON (JCS), определённой в RFC 8785. В результате канонизации создаётся значение JSON с тем же смыслом, что и исходное, но с устойчивым представлением: повторный вызов Canonicalize для уже канонизированного значения ничего не меняет.
Строки JSON форматируются в минимальном представлении, числа JSON — как числа двойной точности с использованием стабильного алгоритма сериализации. Элементы объектов JSON сортируются по именам в порядке возрастания. Все пробельные символы удаляются.
Canonicalize эквивалентен вызову Value.Format со следующими параметрами:
- CanonicalizeRawInts(true)
- CanonicalizeRawFloats(true)
- ReorderRawObjects(true)
Любые параметры, заданные вызывающим кодом, применяются после исходного набора и могут намеренно переопределять предыдущие параметры.
Обратите внимание, что JCS рассматривает все числа JSON как числа двойной точности IEEE 754. Любые числа, точность которых превышает возможности такого представления, потеряют точность при канонизации. Например, целые числа за пределами ±2⁵³ потеряют точность. Чтобы сохранить исходное представление целых чисел JSON, дополнительно задайте для CanonicalizeRawInts значение false:
v.Canonicalize(jsontext.CanonicalizeRawInts(false))
func (Value) Clone 1.27
func (v Value) Clone() Value
Clone возвращает копию v.
func (*Value) Compact 1.27
func (v *Value) Compact(opts ...Options) error
Compact удаляет все пробельные символы из исходного значения JSON.
Метод не переформатирует строки или числа JSON, чтобы использовать другое представление. Чтобы увеличить набор значений JSON, которые можно форматировать, метод допускает значения с повторяющимися именами и некорректным UTF-8.
Compact эквивалентен вызову Value.Format со следующими параметрами:
- AllowDuplicateNames(true)
- AllowInvalidUTF8(true)
- PreserveRawStrings(true)
Любые параметры, заданные вызывающим кодом, применяются после исходного набора и могут намеренно переопределять предыдущие параметры.
func (*Value) Format 1.27
func (v *Value) Format(opts ...Options) error
Format форматирует исходное значение JSON на месте.
По умолчанию (если параметры не заданы) метод выполняет проверку согласно RFC 7493 и формирует минимальное представление JSON, удаляя все пробельные символы и используя для строк JSON кратчайшее представление.
К соответствующим параметрам относятся:
- AllowDuplicateNames
- AllowInvalidUTF8
- EscapeForHTML
- EscapeForJS
- PreserveRawStrings
- CanonicalizeRawInts
- CanonicalizeRawFloats
- ReorderRawObjects
- SpaceAfterColon
- SpaceAfterComma
- Multiline
- WithIndent
- WithIndentPrefix
Все остальные параметры игнорируются.
Гарантируется успешное выполнение, если значение допустимо согласно тем же параметрам. Если значение уже отформатировано, буфер не изменяется.
func (*Value) Indent 1.27
func (v *Value) Indent(opts ...Options) error
Indent заново форматирует пробельные символы в исходном значении JSON так, чтобы каждый элемент объекта JSON или массива начинался с новой строки с отступом, соответствующим уровню вложенности.
Метод не переформатирует строки или числа JSON, чтобы использовать другое представление. Чтобы увеличить набор значений JSON, которые можно форматировать, метод допускает значения с повторяющимися именами и некорректным UTF-8.
Indent эквивалентен вызову Value.Format со следующими параметрами:
- AllowDuplicateNames(true)
- AllowInvalidUTF8(true)
- PreserveRawStrings(true)
- Multiline(true)
Любые параметры, заданные вызывающим кодом, применяются после исходного набора и могут намеренно переопределять предыдущие параметры.
func (Value) IsValid 1.27
func (v Value) IsValid(opts ...Options) bool
IsValid сообщает, является ли исходное значение JSON синтаксически допустимым с учётом заданных параметров.
По умолчанию (если параметры не заданы) метод выполняет проверку согласно RFC 7493. Он проверяет, правильно ли входные данные закодированы в UTF-8, декодируются ли escape-последовательности в строках в допустимые кодовые точки Unicode и уникальны ли все имена в каждом объекте. Метод не проверяет, представимы ли числа в пределах ограничений какого-либо распространённого числового типа (например, float64, int64 или uint64).
К соответствующим параметрам относятся:
Все остальные параметры игнорируются.
func (Value) Kind 1.27
func (v Value) Kind() Kind
Kind возвращает тип начального токена. Для допустимого значения он никогда не будет равен KindEndObject или KindEndArray.
func (Value) MarshalJSON 1.27
func (v Value) MarshalJSON() ([]byte, error)
MarshalJSON возвращает v в виде JSON-кодирования v. Проверка не выполняется. Если v равен nil, возвращается JSON null.
func (Value) String 1.27
func (v Value) String() string
String возвращает строковое представление v.
func (*Value) UnmarshalJSON 1.27
func (v *Value) UnmarshalJSON(b []byte) error
UnmarshalJSON задаёт v как JSON-кодирование b. Метод сохраняет копию переданных исходных данных JSON без какой-либо проверки.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/encoding/json/jsontext/