Pull to refresh

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


Внимание, статья-перевод!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.