Как стать автором
Обновить

JSONT или XSLT для JSON

Часто возникает задача преобразования JSON в другие форматы, особенно в XML или HTML. Очевидное решение заключается в использовании языка программирования (ECMAScript, Ruby, ...) и DOM-API.

XML можно преобразовать в другой XML-документ, с помощью правил преобразования (XSLT) и применяя эти правила с помощью XSLT-процессора.

Следуя этой концепции, я экспериментировал с набором правил преобразования (записанных в JSON). В результате, по аналогии с XML / XSLT сочетание JSON / JSONT может использоваться для преобразования JSON в любом другом формат.


Пример



Начнем с простого JSON:

{
  "link": {
    "uri": "company.com",
    "title": "company homepage"
  }
}


Мы хотим преобразовать его в HTML ссылку

<a href="company.com">company homepage</a>


Для этого напишем соответствующее правило

{
  "link": "<a href=\"{link.uri}\">{link.title}</a>"
}


И используя процессор jsonT(data, rules) применим правило к JSON данным для получения результата

Принцип работы JSONT



Набором правил является простой словарь. Таким образом, каждое правило — это пара (имя, значение).

Имя правила обычно является выражением для доступа к объекту данных. Значение правила — это строка или функция с одним аргументом, которая вычисляется во время трансформации.

"name": "transformation string"
"name": function(arg){ … }


Правило, заданное строкой, может содержать одно или несколько выражений, заключенных в фигурные скобки

{выражение}


Которое всегда становится строкой.
  • Если выражение ссылается на имя правила, то это правило вычисляется
  • Если результатом выражения является простой тип, то его значение конвертируется в строку
  • Если результатом выражение является массив / словарь, то каждый элемент, обрабатывается соответствующим образом
  • Знак $ как часть выражение заменяется на имя правила
  • Если выражение имеет явный вид @name(expr), то вызывается функция name, а возвращаемое значение преобразуется в строку


Выходной JSON объект можно получить с помощью ключевого слова self

Имена правил для элементов массива используют синтаксис name[*]. Если используется знак $ в строке правила, * указывает на индекс массива.

Члены входного объекта, которые не имеют правил трансформации и на которые нет ссылкок, а также выражения, которые вычисляются в undefined не образуют выходных данных.

Ещё примеры


Векторная геометрия

{
  "line": {
    "p1": {
      "x": 2,
      "y": 3
    },
 
    "p2": {
      "x": 4,
      "y": 5
    }
  }
}

+
{
  "self": "<svg>{line}</svg>",
  "line": "<line x1=\"{$.p1.x}\" y1=\"{$.p1.y}\"" + "x2=\"{$.p2.x}\" y2=\"{$.p2.y}\" />"
}

=
<svg><line x1="2" y1="3" x2="4" y2="5" /></svg>


HTML список

["red", "green", "blue"]

+
[
  "self": "<ul>n{$}</ul>",
  "self[*]": "  <li>{$}</li>n"
]

=
<ul>
  <li>red</li>
  <li>green</li>
  <li>blue</li>
</ul>


Двухмерный массив и функция-правило

{
  "color": "blue",
  "closed": true,
  "points": [[10,10],[20,10],[20,20],[10,20]]
}

+
{
  "self": "<svg><{closed} stroke=\"{color}\" points=\"{points}\" /></svg>",
  "closed": function(x) { return x ? "polygon" : "polyline"; }, 
  "points[*][*]": "{$} "
}

=
<svg><polygon stroke="blue" points="10 10 20 10 20 20 10 20 " /></svg>


Полезные ссылки:


  1. Оригинальная статья
  2. JSONT module for CommonJS
  3. Обсуждение на stackoverflow.com


Внимание, статья-перевод!
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.