Как создать XML-документ в Java кратко? - PullRequest
20 голосов
/ 20 июня 2009

Мне нужно построить документ XML из иерархии объектов Java. И классы Java, и формат XML являются фиксированными. Поэтому я не могу использовать XML-сериализатор, такой как XStream : он основывает формат XML на классах Java. Аналогично, технология связывания Java XML, такая как JAXB , не будет работать, поскольку она создает классы Java из схемы XML [ed:, но см. Ниже]. Мне нужен ручной подход.

Низкотехнологичный маршрут StringBuilder приводит к хрупкому и глючному коду (по крайней мере, для меня!).

API, такой как JAXP или JDOM , приводит к гораздо более надежному коду, но они довольно многословны.

Groovy имеет элегантный MarkupBuilder :

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.records() {
  car(name:'HSV Maloo', make:'Holden', year:2006) {
    country('Australia')
    record(type:'speed', 'Production Pickup Truck with speed of 271kph')
  }
  car(name:'P50', make:'Peel', year:1962) {
    country('Isle of Man')
    record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg')
  }
}

В других языках (например, Ruby ) есть даже лучшие, хотя я хочу остаться с чистой Java. Кажется, что есть некоторые новые XML-компоновщики для Java, такие как Practicalxml и Джеймс Мёрти xmlbuilder .

Каковы более элегантные подходы для создания XML-документов в Java?

Резюме:

Джон Доу предложил dom4j и jdom .

CurtainDog рекомендовал использовать JAXB в любом случае, и jherico подсказал мне, что это было уместное предложение: вы могли бы затем использовать Dozer для сопоставления между моим текущим JavaBeans и JAXB JavaBeans.

thaggie рекомендует JIBX и соглашается с CurtainDog и jherico, что технологии связывания действительно практичны.

StaxMan рекомендует StaxMate .

Из вещей, на которые я смотрел, Practicalxml и xmlbuilder Джеймса Мёрти кажутся наиболее лаконичными, но довольно новы. Технологии переплета, такие как JAXB, обеспечивают дополнительную безопасность / автоматизацию. Из основного выбора dom4j выглядит прилично, хотя все еще довольно многословно. Он предлагает «свободный интерфейс» (мутаторы возвращают ссылку на мутированный объект, чтобы их можно было объединить в цепочку), который мне нравится:

public Document createDocument() {
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement( "root" );
    Element author2 = root.addElement( "author" )
      .addAttribute( "name", "Toby" )
      .addAttribute( "location", "Germany" )
      .addText( "Tobias Rademacher" );
    Element author1 = root.addElement( "author" )
      .addAttribute( "name", "James" )
      .addAttribute( "location", "UK" )
      .addText( "James Strachan" );
    return document;
}

Для краткости вы можете обернуть тонкий интерфейс поверх этого API, чтобы обеспечить краткие синонимы для некоторых из этих методов (например, attr () вместо addAttribute ()).

Спасибо всем!

P.S .: Стефан Шмидт работал над Java MarkupBuilder , хотя, похоже, не опубликовал его.

Ответы [ 5 ]

10 голосов
/ 20 июня 2009

dom4j или jdom, пожалуй, самые элегантные, вы можете написать код так, как вам нравится. У Dom4j есть конструкторы, если я помню, и да, код более подробный.

Element.addElement("x").setAttribute("x", "y").xxxxx;
2 голосов
/ 15 июля 2009

Взгляните на XOM . Это быстро, просто, правильно и не многословно.

1 голос
/ 20 июня 2009

Хотя и не такой лаконичный, как разработчики языков сценариев, StaxMate делает все довольно просто; как правило, структурно проста, как древовидная модель, но дополнительно поддерживает типизированное сложение (неявные преобразования). И делает все это непосредственно в потоке, что означает очень низкое использование памяти (и высокую скорость, если это имеет значение).

Для чего бы то ни было, он также поддерживает свободный стиль (начиная с 2.0.x), поскольку он часто имеет смысл. Основное преимущество по сравнению с решениями для полной привязки данных (и древовидной модели), вероятно, заключается в низком использовании памяти; очень небольшое состояние сохраняется вокруг, все выходные данные отправляются в пункт назначения как можно скорее.

1 голос
/ 20 июня 2009

Почему бы вам просто не использовать JAXB в любом случае ... тогда проблема становится очень простым сопоставлением объектов и вы вообще избегаете xml.

0 голосов
/ 20 июня 2009

Вы можете рассмотреть JIBX , вы можете определить отображение из классов вашей доменной модели в вашу целевую XML-схему.

В качестве альтернативы, если это невозможно, хотя я знаю, что вы заявляете, что у вас есть скидки, используя технологии привязки, я бы посоветовал вам пересмотреть это решение, копирование из вашей доменной модели в сгенерированную модель, скорее всего, приведет к более чистым, более обслуживаемый и менее подверженный ошибкам код, чем тот, который вы предлагаете (что также может делать JIBX).

Я, вероятно, должен добавить, что, по моему опыту, задавать вопросы о JIBX здесь бесполезно, но их список рассылки очень полезен.

...