Создание classа JAXB, который реализует интерфейс

В настоящее время я использую JAXB для создания classов java, чтобы развязать XML. Теперь я хотел бы создать новую схему, очень похожую на первую, и создать classы, реализующие один и тот же интерфейс.

Скажем, например, у меня есть два файла схемы, которые определяют XML с похожими тегами:

adult.xsd

          

kid.xsd

           

Используя JAXB и XJC, я хотел бы сгенерировать два файла classа:

 public class Adult implements Person { ... public String getName() { ... } public int getAge() { ... } public String getJob { ... } } public class Kid implements Person { ... public String getName() { ... } public int getAge() { ... } public String getSchool { ... } } 

где интерфейс Person определяет getName() и getAge() .

Я просмотрел некоторые документы для сопоставления интерфейсов, но это, по-видимому, относится только к ситуации, когда у вас уже есть classы Java, которые вы хотите сопоставить с DOM.

Кроме того, я пытался использовать этот внешний плагин, но он не работает. Вот мой файл привязки xjb:

   mypackage.Hello   

но это приводит к следующей ошибке:

 $ java -cp "lib/activation.jar;lib/InterfacesXJCPlugin.jar;lib/jaxb1-impl.jar;lib/jaxb-api.jar;lib/jaxb-xjc.jar;lib/jsr173_1.0_api.jar" com.sun.tools.xjc.XJCFacade -p mypackage.myxml -extension -Xinterfaces xsd/adult.xsd -b binding.xjb parsing a schema... [ERROR] XPath evaluation of "xs:schema/xs:complexType[@name='Person']" results in empty target node line 8 of file:/C:/dev/jaxb/jaxb-ri/binding.xjb Failed to parse a schema. 

Можно ли создать class с JAXB, который реализует интерфейс?

Обновить

Я пробовал использовать плагин Interface Insertion, но по какой-то причине не могу заставить его работать. Это то, как я называю xjc, но это похоже на то, что плагин-плагин не получает из classа pathpath:

 $ java -cp "lib/xjc-if-ins.jar;lib/jaxb-xjc.jar" com.sun.tools.xjc.XJCFacade -p mypackage -extension -Xifins myschema.xsd -b binding.xjb 

Я получаю сообщение об ошибке:

 unrecognized parameter -Xifins 

Есть идеи?

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

К счастью, JAXB2 Basics Plugins предоставляет аналогичный механизм для добавления интерфейса к сгенерированным JAXB-заглушкам (см. Плагин Inheritance ).

В документации плагина Inheritance приведен пример, показывающий, как выглядит файл схемы XML. Однако, поскольку вы не можете изменить схему, вы можете использовать внешний файл привязок:

     mypackage.Hello    

Документация JAXB2 Basics Plugins содержит инструкции по использованию плагина с Ant и Maven. Вы также можете использовать его прямо из командной строки, но команда немного беспорядочна (из-за количества банок, которые вы должны добавить в путь к classам):

 java -jar jaxb-xjc.jar -classpath jaxb2-basics-0.5.3.jar,jaxb2-basics-runtime-0.5.3.jar, jaxb2-basics-tools-0.5.3.jar,commons-beanutils-0.5.3.jar, commons-lang.jar,commons-logging.jar -p mypackage.myxml -extension -Xinheritance xsd/adult.xsd -b binding.xjb 

Плагины JAXB2 Basics предоставляют ряд других утилит, которые вы также можете найти полезными (например, автогенерация методов equals, hashCode и toString).

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

Вы объявляете аспект по строкам:

 public aspect MyAspect { declare parents: com.foo.generated.Adult implements com.foo.Person; declare parents: com.foo.generated.Kid implements com.foo.Person; } 

Что добавит интерфейс com.foo.Person к classам com.foo.generated.Adult и com.foo.generated.Adult

Может быть, излишним для вашей цели, но это сработало для нас.

Ответ, который сработал для меня, – это пример использования Jim X2’s плагина Basics. Но связанная с ним документация больше не доступна, поэтому для справки, вот как я настроил плагин maven:

   org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.8.2    generate     true  -Xinheritance  src/main/resources/xjb  **.xml   src/main/resources/xsd ${project.build.directory}/generated-sources/jaxb mypackage   org.jvnet.jaxb2_commons jaxb2-basics 0.5.3     

Это можно сделать для этого простого случая без использования плагина третьей стороны с использованием расширения JAXB RI Vendor Extensions xjc: superInterface. Следует отметить, что этот подход заставит все созданные classы реализовать интерфейс.

Пример файла привязки:

        

Затем вам просто нужно запустить xjc, указав файл привязки и установив флаг -extension . Гораздо быстрее / проще, чем приносить JAXB2Basics!

Я был скептически настроен, что это будет работать, поскольку в документации указано:

Настройка позволяет указать полное имя интерфейса Java, которое должно использоваться в качестве корневого интерфейса всех созданных интерфейсов. Эта настройка не имеет эффекта, если вы специально не генерируете интерфейсы с помощью globalBindings generateValueClass = “false”.

Но когда я попробовал это с привязками, подобными приведенному выше (без указания generateValueClass = “false” и генерации classов, а не интерфейсов), он дал мне требуемый результат – все мои сгенерированные classы реализовали общий интерфейс.

В моем случае вызов командной строки через java -jar работает:

java -jar $somepath/jaxb-xjc.jar -classpath $somepath/xjc-if-ins.jar my.xsd -d $destdir -b $bindingconfig -p $desiredpackage -extension -Xifins

Однако при выполнении ant-задачи xjc ошибка сохраняется. Сообщение об ошибке является раздражающим, так как реальная причина в моем случае – это неправильный номер версии в файле classа ant, который пытается загрузить (см. Таблицу stacktrace ниже). Это правильное сообщение об ошибке появляется только при добавлении в ANT_OPTS следующего: -Dcom.sun.tools.xjc.Options.findServices=true

 [xjc] java.lang.UnsupportedClassVersionError: Bad version number in .class file [xjc] at java.lang.ClassLoader.defineClass1(Native Method) [xjc] at java.lang.ClassLoader.defineClass(ClassLoader.java:620) [xjc] at org.apache.tools.ant.AntClassLoader.defineClassFromData(AntClassLoader.java:1134) [xjc] at org.apache.tools.ant.AntClassLoader.getClassFromStream(AntClassLoader.java:1320) [xjc] at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1376) [xjc] at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:1336) [xjc] at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:1074) [xjc] at java.lang.ClassLoader.loadClass(ClassLoader.java:299) [xjc] at java.lang.ClassLoader.loadClass(ClassLoader.java:251) [xjc] at com.sun.tools.xjc.Options.findServices(Options.java:936) [xjc] at com.sun.tools.xjc.Options.getAllPlugins(Options.java:336) [xjc] at com.sun.tools.xjc.Options.parseArgument(Options.java:632) [xjc] at com.sun.tools.xjc.Options.parseArguments(Options.java:742) [xjc] at com.sun.tools.xjc.XJC2Task._doXJC(XJC2Task.java:444) [xjc] at com.sun.tools.xjc.XJC2Task.doXJC(XJC2Task.java:434) [xjc] at com.sun.tools.xjc.XJC2Task.execute(XJC2Task.java:369) [xjc] at com.sun.istack.tools.ProtectedTask.execute(ProtectedTask.java:55) [xjc] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) [xjc] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [xjc] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [xjc] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [xjc] at java.lang.reflect.Method.invoke(Method.java:585) [xjc] at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) [xjc] at org.apache.tools.ant.Task.perform(Task.java:348) [xjc] at org.apache.tools.ant.Target.execute(Target.java:390) [xjc] at org.apache.tools.ant.Target.performTasks(Target.java:411) [xjc] at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1360) [xjc] at org.apache.tools.ant.Project.executeTarget(Project.java:1329) [xjc] at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) [xjc] at org.apache.tools.ant.Project.executeTargets(Project.java:1212) [xjc] at org.apache.tools.ant.Main.runBuild(Main.java:801) [xjc] at org.apache.tools.ant.Main.startAnt(Main.java:218) [xjc] at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) [xjc] at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) [xjc] [xjc] failure in the XJC task. Use the Ant -verbose switch for more details 

Документация для плагина интерфейса-вставки предлагает следующее

[Чтобы вызвать xjc с плагином вставки интерфейса из командной строки, вы можете написать:

 java -cp $JAXB_HOME/share/lib/xjc-if-ins.jar -extension -Xifins schema 

]

Я предполагаю, что вы вызываете основной метод неправильного classа – com.sun.tools.xjc.XJCFacade. Вероятно, вы должны повторить попытку с точным синтаксисом.

Вот ссылка на другом форуме, в котором обсуждается аналогичная проблема. http://forums.java.net/jive/message.jspa?messageID=220686

  • Я бы разместил это как комментарий, но у меня недостаточно комментариев для комментариев.

Что делать, если вы извлекаете тип в обычный XSD, импортированный в adult.xsd и kid.xsd? Или у вас есть существующий интерфейс, который вам нужно реализовать?

Для тех, кто хотел бы помочь создать файлы привязки данных JAXB для более сложной схемы – новейшего инструмента XML с открытым исходным кодом – CAM Editor v2.2 теперь поддерживает это.

Вы можете получить доступ к ресурсам и загрузить сайт для пошагового руководства и просмотреть раздел загрузки на странице вверх для инструмента.

http://www.cameditor.org/#JAXB_Bindings

Наслаждаться.

XJC plygin какого-то описания – это ответ на вашу проблему, это всего лишь вопрос поиска того, что работает. Лучший источник для них:

https://jaxb2-commons.dev.java.net/

В частности, это:

https://jaxb2-commons.dev.java.net/interface-insertion/

  • Как связать XML с XSD с помощью schemaLocation или noNamespaceSchemaLocation?
  • Сгенерировать class C # из XML
  • Для чего нужны пространства имен XML?
  • Есть ли разница между «действительным xml» и «хорошо сформированным xml»?
  • Как сгенерировать образцы XML-документов из их DTD или XSD?
  • JAXB: Как изменить имена classов, сгенерированных XJC, когда тип attr указан в XSD?
  • XML-схема minOccurs / maxOccurs значения по умолчанию
  • Как я могу сказать jaxb / Maven для создания нескольких пакетов схем?
  • Создание WSDL из файла XSD
  • API Java для анализа файла схемы XSD
  • xmlns, xmlns: xsi, xsi: schemaLocation и targetNamespace?
  • Interesting Posts

    Как cookies передаются в HTTP-протоколе?

    Убывающий список упорядочен по времени изменения файла

    Преимущества / Недостатки разделения диска

    Как восстановить ярлыки (.lnk-файл) в Windows 7?

    Сделать grub сохранить загрузку по умолчанию под обновлениями ядра

    iPhone SDK: как вы загружаете видеофайлы в Справочник документов, а затем воспроизводите их?

    Как предотвратить закрытие программ после выполнения командного файла?

    Используйте значение из предыдущей строки в расчете R.table.table

    Анализ XML-документа в C #

    Как я могу изменить или заменить все экземпляры символа в текстовом файле на новую строку / разрыв строки / EOL в Notepad2 или Notepad ++?

    Есть ли разница в производительности между i ++ и ++ i в C ++?

    Могу ли я спящий режим Linux без раздела подкачки?

    Хранить и работать с большими номерами в C

    Сборка – JG / JNLE / JL / JNGE после CMP

    Как установить правильные разрешения для файла ASP.NET для IIS

    Давайте будем гением компьютера.