2011-09-07 2 views
3

Я использую org.jvnet.jaxb2.maven2:maven-jaxb2-plugin для создания POJO из файлов схемы XSD.Вставить пользовательский сеттер в maven-jaxb2-plugin

Теперь я хочу вставить что-то вроде настраиваемого сеттера. Он должен обрезать все строки и удалить некоторые символы.

Вы знаете, как это сделать?


Файл XJB:

<?xml version="1.0" encoding="UTF-8"?> 
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> 
    <jaxb:bindings schemaLocation="my-schema-xml4.xsd" node="/xs:schema"> 
     <xjc:javaType name="java.lang.String" adapter="my.StringAdapter" /> 
    </jaxb:bindings> 
</jaxb:bindings> 

Раствор для связывания типов Java:

<?xml version="1.0" encoding="UTF-8" ?> 
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"> 
    <bindings schemaLocation="mySchema-xml4.xsd" node="/xs:schema"> 
     <globalBindings> 
      <xjc:javaType name="java.lang.String" xmlType="xs:string" 
       adapter="com.name.MyAdapter" /> 
        <xjc:javaType name="java.lang.String" xmlType="xs:anySimpleType" 
       adapter="com.name.MyAdapter" /> 
     </globalBindings> 
    </bindings> 
</bindings> 

Но @XmlJavaTypeAdapter по-прежнему не добавляется в content недвижимость в узлах со смешанным контентом, хотя свойство имеет тип java.lang.String.

ответ

1

Я думаю, что лучший способ достичь этого - реализовать собственный XmlAdapter и настроить его с помощью настройки свойств. Вы можете сделать это со стандартной настройкой jaxb:property или с annotate plugin.

jaxb:property:

<jaxb:property> 
    <jaxb:baseType> 
     <xjc:javaType name="java.lang.String" 
     adapter="com.acme.foo.MyAdapter"/> 
    </jaxb:baseType> 
    </jaxb:property> 

Annotate плагин:

<annox:annotate target="field"> 
    <annox:annotate 
     annox:class="javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter" 
     value="com.acme.foo.MyAdapter"/> 
    </annox:annotate> 

Смотрите образец проекта здесь:

https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/tests/one/

+0

Я реализовал XmlAdapter, но я не знаю, как его добавить. Посмотрите мой XJB-файл в отредактированном вопросе. –

+1

Пожалуйста, перечитайте мой ответ: 'jaxb: property' - это путь. Есть также ссылка на образец проекта - вы проверили это? – lexicore

+0

Я перечитал ваш ответ, а также проверил образец проекта, но я не знаю, где добавить свойство jaxb:, когда я хочу, чтобы он затронул все строки в схеме. –

0

Если XSD не изменится в будущем только генерировать POJO, закомментируйте плагин JAXB и измените источник вручную.

Если ваш XSD меняется редко, вы все еще можете использовать это решение с системой контроля версий. Зафиксируйте созданный источник, измените POJO и выполните изменения. В следующий раз, когда XSD будет изменен, создайте патч между двумя коммитами, сгенерируйте POJO из нового XSD и примените патч. Я нашел это решение намного проще в тех случаях, когда XSD почти никогда не меняется.

+0

К сожалению, я получаю исключение 'javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory не найден, когда я хочу создать новый' XMLInputFactory'. –

0

Альтернативный подход заключается в использовании StAX StreamReaderDelegate для управления XML-текстом до его получения реализацией JAXB.

Demo

Ваш код будет выглядеть примерно следующим образом. Вы бы реализовать StreamReaderDelegate манипулировать текст, возвращенный из текстовых событий:

package forum7329881; 

import java.io.FileInputStream; 
import javax.xml.bind.*; 
import javax.xml.stream.*; 
import javax.xml.stream.util.StreamReaderDelegate; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Customer.class); 

     XMLInputFactory xif = XMLInputFactory.newInstance(); 
     XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum7329881/input.xml")); 
     xsr = new MyStreamReaderDelegate(xsr); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Customer customer = (Customer) unmarshaller.unmarshal(xsr); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(customer, System.out); 
    } 

    private static class MyStreamReaderDelegate extends StreamReaderDelegate { 

     public MyStreamReaderDelegate(XMLStreamReader xsr) { 
      super(xsr); 
     } 


     @Override 
     public String getText() { 
      return super.getText().trim(); 
     } 

     @Override 
     public char[] getTextCharacters() { 
      return getText().toCharArray(); 
     } 

     @Override 
     public int getTextLength() { 
      return getText().length(); 
     } 

     @Override 
     public int getTextStart() { 
      return 0; 
     } 

    } 

} 

входа.XML

Ниже приведен пример ввода, который содержит пробелы в текстовых узлах:

<customer Id="1"> 
    <name> Jane Doe </name> 
    <address> 
     <street> 123 A Street </street> 
    </address> 
</customer> 

Выходной

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<customer> 
    <address> 
     <street>123 A Street A</street> 
    </address> 
    <name>Jane Doe</name> 
</customer> 

Клиент

package forum7329881; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Customer { 

    private String name; 
    private Address address; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 

Адрес

package forum7329881; 

public class Address { 

    private String street; 

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

} 

Для получения более подробной информации

Ниже приводится ссылка на более подробный пример, где я использовал StAX StreamReaderDelegate для поддержки чувствительно к регистру демаршаллинг:

0

На мой взгляд, вы должны использовать AOP, Pick Spring AOP, например, перехватите методы адаптера, чтобы иметь логику обрезки/полосы. На самом деле это теперь может быть общей логикой, которая применима ко всем строковым типам. Если это звучит убедительно, я могу помочь с кодом

+0

Мне просто нужно знать, куда вставить перехватчик. –

 Смежные вопросы

  • Нет связанных вопросов^_^