Допустим, у меня есть API-интерфейс REST в Java, и он поддерживает ответы в формате JSON или XML. Ответы содержат те же данные, но форма не идентична. Например, в JSON я мог бы иметь:
{
"persons": [
{
"name":"Bob",
"age":24,
"hometown":"New York"
}
]
}
Тогда как в XML это выглядит так:
<persons>
<person name="bob" age="24">
<hometown>New York</hometown>
</person>
</persons>
То есть некоторые значения являются атрибутами личности, а другие - дочерними элементами. В Java, используя JAXB и Джексона, легко скрыть такие различия с помощью аннотаций на объектах модели, например:
public class Person {
@XmlAttribute
String name;
@XmlAttribute
Integer age;
@XmlElement
String hometown;
}
JAXB читает аннотации, а Джексон использует имена полей, чтобы выяснить, что делать. Таким образом, с одной моделью легко поддерживать несколько форматов вывода.
Итак, мой вопрос, как сделать то же самое в clojure. Я знаю, что есть clj-json, который может легко конвертировать карты и векторы clojure в json (используя Джексона, если я не ошибаюсь). И я знаю, что есть и clojure.xml.emit, и clojure.contrib.xml.prxml, которые могут десериализовать карты и векторы в XML. Но если я не ошибаюсь, я не думаю, что эти два будут работать вместе очень хорошо.
Поскольку prxml ожидает, что узлы xml будут выражаться как векторы, а атрибуты xml - как карта, это принципиально отличается от работы clj-json, где векторы представляют массивы, а карты представляют объекты. И clojure.core.emit ожидает карту в форме {:tag :person :attrs {:name "Bob" :age 24} :content ...}
, которая снова полностью отличается от того, что хочет clj-json.
Единственное, о чем я могу думать, это отформатировать структуры данных для prxml в моем коде, а затем написать функцию, которая преобразует структуру данных в то, что хочет clj-json, когда типом ответа является JSON. Но это кажется отстойным. Я бы предпочел, чтобы была пара библиотек JSON и XML, которые были бы совместимы так, как это делают JAXB и Джексон.
Идеи