кастомизация в JAXB

 
 
 
Сообщения:17
На основе xsd можно получить классы для маршалинга\демаршалинга. Делается это с помощью утилиты, входящей в JDK... как можно настраивать (кастомизировать?) генерацию классов? Что гуглить?

Кстати, нашел вот одну ссылку... в моей схеме тоже есть choice ... почему это плохо?
		<xs:element name="Document" maxOccurs="unbounded">
											<xs:complexType>
												<xs:choice>


относится ли вот это к теме?

http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/tutorial/doc/JAXBUsing4.html

+ 23.12.2016 https://luisfsgoncalves.wordpress.com/2010/06/26/jaxb-and-xsdchoice/
Изменен:23 дек 2016 07:29
 
 
Сообщения:140
относится

 
 
Сообщения:17
в xsd есть код

<xs:element name="Document" maxOccurs="unbounded">
	<xs:complexType>
		<xs:choice>

			<xs:group ref="PassportRF"/>
			<xs:group ref="SNILS"/>

			<xs:group ref="OrderAdmission"/>
			<xs:group ref="OrderDismissal"/>
			<xs:group ref="OrderTransfer"/>

			<xs:group ref="HealthInformation"/>

			<xs:group ref="CertificationCSE"/>

		</xs:choice>
		<xs:attribute ref="type" use="required"/>
		<xs:attribute ref="ver" use="required"/>
	</xs:complexType>
</xs:element>


ну и потом каждая группа определяется

	<xs:group name="PassportRF">
		<xs:sequence>
			<xs:annotation>
				<xs:documentation>Паспорт гражданина РФ type="11" ver="1"</xs:documentation>
			</xs:annotation>

			<xs:element name="d_11_1_Series">
				<xs:annotation>
					<xs:documentation>Серия</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="PassportSeries"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_Number">
				<xs:annotation>
					<xs:documentation>Номер</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="PassportNumber"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_LastName">
				<xs:annotation>
					<xs:documentation>Фамилия</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="FI"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_FirstName">
				<xs:annotation>
					<xs:documentation>Имя</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="FI"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_MiddleName" minOccurs="0">
				<xs:annotation>
					<xs:documentation>Отчество</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="MiddleName"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_IssuedBy">
				<xs:annotation>
					<xs:documentation>Кем выдан</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="Text"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_IssueDate">
				<xs:annotation>
					<xs:documentation>Дата выдачи</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="DateType"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

			<xs:element name="d_11_1_UnitCode" minOccurs="0">
				<xs:annotation>
					<xs:documentation>Код подразделения</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:simpleContent>
						<xs:extension base="UnitCode"/>
					</xs:simpleContent>
				</xs:complexType>
			</xs:element>

		</xs:sequence>
	</xs:group>



при маршалинге эти документы выгружаются с реквизитами, имена которых определяются по дефолту... а нужно удалить эту приписку d_XX_Y_
залез ручками и поправил @XmlElement(name = "d_11_1_Number") просто на @XmlElement(name = "Number") - получил нужный мне результат

интересно, на сколько такое решение красивое\правильное и можно ли такое настроить с помощью операторов кастомизации привязок?
Изменен:26 дек 2016 03:40
 
 
Сообщения:155
Если есть возможность редактирования XSD файла перед его использованием, то можно сделать XSLT преобразование нужных атрибутов (лучше через XSLT 2.0, так как там можно использовать регулярные выражения).
 
 
Сообщения:17
спасибо за ответ

на счет возможности редактирования xsd не понял
xsd спускается из министерства (причем будет множество версий) ... да и к сожалению с xslt пока не знаком... хотя физически изменять \ редактировать xsd могу

но всё же... можете поподробней рассказать как это через xslt делается? какая связь между jaxb и xslt?
 
 
Сообщения:155
Как-то так:
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;

/*
 * Для того, чтобы использовать XSLT 2.0 надо подключить соответствующую библиотеку, например Saxon-HE-9.7.0-14.jar
 */
public class XSDTransformer
{
   public static void main(String[] args)
   {
      Source sourceXSD = new StreamSource(new InputStreamReader(new ByteArrayInputStream(XSD_SCHEMA.getBytes())));
      Source xslt = new StreamSource(new StringReader(XSL_TEMPLATE));
      String result = XSDTransformer.toTransformedXSD(sourceXSD, xslt);
      System.out.println(result);
   }

   public static String toTransformedXSD(Source sourceXSD, Source xslt)
   {
      String resultString = null;

      try
      {
         StreamResult outputXSD = new StreamResult(new StringWriter());

         System.setProperty("javax.xml.transform.TransformerFactory","net.sf.saxon.TransformerFactoryImpl");
         TransformerFactory tf = TransformerFactory.newInstance();
         Transformer transformer = tf.newTransformer(xslt);
         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
         transformer.transform(sourceXSD, outputXSD);

         resultString = outputXSD.getWriter().toString();
      }
      catch(TransformerException ex)
      {
         ex.printStackTrace();
      }

      return resultString;
   }

   private static final String XSD_SCHEMA =
           "<?xml version=\"1.0\" encoding=\"utf-8\"?> \n" +
           "<xs:schema elementFormDefault=\"qualified\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"> \n" +
           "  <xs:element name=\"Address\"> \n" +
           "    <xs:complexType> \n" +
           "      <xs:sequence> \n" +
           "        <xs:element name=\"d_11_1_Recipient\" type=\"xs:string\" /> \n" +
           "        <xs:element name=\"d_22_2_House\" type=\"xs:string\" /> \n" +
           "        <xs:element name=\"d_55_5_Street\" type=\"xs:string\" /> \n" +
           "        <xs:element name=\"Town\" type=\"xs:string\" /> \n" +
           "        <xs:element name=\"County\" type=\"xs:string\" minOccurs=\"0\" /> \n" +
           "        <xs:element name=\"PostCode\" type=\"xs:string\" /> \n" +
           "        <xs:element name=\"Country\"> \n" +
           "          <xs:simpleType> \n" +
           "            <xs:restriction base=\"xs:string\"> \n" +
           "              <xs:enumeration value=\"FR\" /> \n" +
           "              <xs:enumeration value=\"DE\" /> \n" +
           "              <xs:enumeration value=\"ES\" /> \n" +
           "              <xs:enumeration value=\"UK\" /> \n" +
           "              <xs:enumeration value=\"US\" /> \n" +
           "            </xs:restriction> \n" +
           "          </xs:simpleType> \n" +
           "        </xs:element> \n" +
           "      </xs:sequence> \n" +
           "    </xs:complexType> \n" +
           "  </xs:element> \n" +
           "</xs:schema>";

   private static final String XSL_TEMPLATE =
           "<xsl:stylesheet version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" " +
           "                                xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" +
           "<xsl:template match=\"@* | node()\">\n" +
           "   <xsl:copy>\n" +
           "      <xsl:apply-templates select=\"@* | node()\"/>  \n" +
           "   </xsl:copy>\n" +
           "</xsl:template>\n" +

           "<xsl:template match=\"xs:element[matches(@name,'d_\\d{2}_\\d{1}_.*')]\">" +
           "   <xsl:copy>" +
           "      <xsl:attribute name=\"name\">\n" +
           "         <xsl:value-of select=\"replace(@name, 'd_\\d{2}_\\d{1}_', '')\"/>\n" +
           "      </xsl:attribute>" +
           "      <xsl:apply-templates select=\"@*[not(local-name()='name')]|node()\"/>" +
           "   </xsl:copy>" +
           "</xsl:template>" +

           "</xsl:stylesheet>";
}


UPD: если использовать maven, то с помощью плагинов "xml-maven-plugin" и "jaxb2-maven-plugin" процесс преобразования xsd файлов и генерацию исходников можно автоматизировать.
Изменен:29 дек 2016 11:13
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет