Как должна работать экранирующая тильда в RFC исправления JSON?

#json #patch #json-patch #rfc6902

#json #исправление #json-patch #rfc6902

Вопрос:

Ссылка https://www.rfc-editor.org/rfc/rfc6902#appendix-A.14:

A.14. ~ Порядок экранирования

Пример целевого документа JSON:

 {
  "/": 9,
  "~1": 10
}
  

Документ исправления JSON:

 [
  {"op": "test", "path": "/~01", "value": 10}
]
  

Результирующий документ JSON:

 {
  "/": 9,
  "~1": 10
}
  

Я пишу реализацию этого RFC, и я застрял на этом. Чего это пытается достичь и как это должно работать?

Предполагая, что ответ на первую часть — «Разрешить ссылаться на имена ключей json, содержащие / s», как бы вы это сделали?

Ответ №1:

~ Символ является ключевым словом в указателе JSON. Следовательно, нам нужно «закодировать» его как ~0 . Цитировать jsonpatch.com,

Если вам нужно обратиться к ключу с помощью ~ или / в его имени, вы должны экранировать символы с помощью ~ 0 и ~ 1 соответственно. Например, чтобы получить «baz» из { «foo/bar ~»: «baz» }, вы должны использовать указатель /foo ~ 1bar ~ 0

Итак, по сути,

 [
  {"op": "test", "path": "/~01", "value": 10}
]
  

при декодировании выдает

 [
  {"op": "test", "path": "/~1", "value": 10}
]
  

Комментарии:

1. Довольно неточная формулировка на jsonpatch.com Я должен сказать. В нем говорится «вы должны экранироваться», хотя это не имеет ничего общего с «escape». На самом деле это замена, а не экранирование. Вы должны заменить ~ на ~0 и / на ~1 .

Ответ №2:

~0 расширяется до ~ so /~01 расширяется до /~1

Я предполагаю, что они означают, что вы не должны «дважды расширять», чтобы расширенное /~1 не должно снова // расширяться и, следовательно, не должно соответствовать ключу documents "/" (что произойдет, если вы дважды расширитесь). Также не следует расширять литералы в исходном документе, чтобы "~1" ключ был буквально таким, а не эквивалентным расширенному "/" . Но я повторяю, что это мое предположение о намерении этого примера, реальное намерение может быть другим.

Пример действительно действительно плохой, в частности, поскольку он использует "test" операцию и не указывает результат этой операции. В других примерах, подобных следующему в A.15, по крайней мере, говорится, что его тестовая операция должна завершиться неудачей, A.14 не сообщает вам, должна ли операция завершиться успешно или нет. Я предполагаю, что они имели в виду, что операция должна быть успешной, так что это подразумевает /~01 "~1" , что ключ должен совпадать. Это, наверное, все об этом примере.

Если бы я должен был написать реализацию, я бы, вероятно, не слишком беспокоился об этом примере и просто посмотрел, что делают другие реализации — чтобы проверить, совместим ли я с ними. Также неплохо поискать наборы тестов других проектов, например, я нашел один из http://jsonpatch.com / в https://github.com/json-patch/json-patch-tests

Ответ №3:

Я думаю, что пример, приведенный в RFC, не совсем хорошо продуман, особенно потому, что он пытается документировать функцию только с помощью примера, который в лучшем случае является расплывчатым — без предоставления каких-либо комментариев.

Вас может заинтересовать интерпретация, представленная в следующих документах:

Они кажутся ужасно похожими, и я думаю, что это связано с характером отношений между Rackspace и OpenStack:

OpenStack начался в 2010 году как совместный проект Rackspace Hosting и NASA (…)

На самом деле он предоставляет некоторые полезные детали, включая грамматику, которую он принимает, и обоснование введения этих токенов, в отличие от самого RFC.

Редактировать: похоже, что указатели JSON имеют отдельный RFC 6901, который доступен здесь, и спецификации OpenStack и Rackspace, приведенные выше, соответствуют этому.