Еще один обязательный вопрос Jaxb - PullRequest
1 голос
/ 17 августа 2011

Я думаю, что наконец-то сузил одну из своих проблем.Я использую Jaxb W / Moxy реализации.Я использую нотацию Xpath в моем файле привязки.Я не получаю желаемых результатов.

Исходный класс, сгенерированный jaxb, сильно вложен, для тестирования я уменьшил код до приведенного ниже Condition.java.

Condition.java

 @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "condition", propOrder = {
        "diagnosisPriority",
        "problemDate",
        "problemType",
        "problemName",
        "problemCode",
        "ageAtOnset",
        "problemStatus",
        "comment"
    })

public  class Condition {

    protected BigInteger diagnosisPriority;
    protected IvlTs problemDate;
    protected Cd problemType;
    @XmlElement(required = true)
    protected Object problemName;
    protected Cd problemCode;
    protected BigInteger ageAtOnset;
    protected Ce problemStatus;
    protected List<Comment> comment;

//ommitted getters and setters

Класс I создан: conditionConnect.java

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class conditionConnect {
     private Condition connectX;

    public Condition getconditionConnect() {
        return connectX;
    }

    public void setconditionConnect(Condition connectX) {
        this.connectX = connectX;
    }
}

Моим первым тестом было создание объектной модели и ее преобразование в xml.Это было сделано успешно с кодом ниже:

public static void main(String[] args) {

    try {
      int AgeInt = 36;
      int DiagnoseInt = 5;
      Condition InstCon = new Condition();
      Cd myProblem = new Cd();
      InstCon.setDiagnosisPriority(BigInteger.valueOf(DiagnoseInt));
      InstCon.setProblemType(myProblem);
      InstCon.setProblemName("I have Asthma");
      InstCon.setAgeAtOnset(BigInteger.valueOf(AgeInt)); 
      myProblem.setCode("1223343");
      myProblem.setCodeSystem("23433.23232.23232");
      myProblem.setDisplayName("Asthma");
      myProblem.setCodeSystemName("ICD-9");

    JAXBContext jc1 = JAXBContext.newInstance(conditionConnect.class);
    Marshaller marshaller1 = jc1.createMarshaller();
    marshaller1.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    conditionConnect conVar = new conditionConnect();
    conVar.setconditionConnect(InstCon);
    marshaller1.marshal(conVar, System.out);

Вывод так (успех!):

   <conditionConnect>
      <diagnosisPriority>5</ns0:diagnosisPriority>
      <problemType code="1223343" displayName="Asthma" codeSystem="23433.23232.23232" codeSystemName="ICD-9"/>
      <problemName>I have Asthma</ns0:problemName>
      <ageAtOnset>36</ageAtOnset>
   </conditionConnect>

Поскольку я буду получать данные через строку / файл xml, я решилиспользуйте файл привязки.Ниже приведена выдержка для класса Condition:

problem.xml - ввод данных

<PROBLEM_MODULE>
  <ID>91</ID>
  <PR_ID>124</PR_ID>
  <PROBLEM_TYPE>T</PROBLEM_TYPE>
  <PROBLEM_NAME>Asthma</PROBLEM_NAME>
  <PROBLEM_CODE>244.9</PROBLEM_CODE>
  <PATIENT_AWARENESS>N</PATIENT_AWARENESS>
  <TREATING_PROVIDER_ID>23456</TREATING_PROVIDER_ID>
  <PROBLEM_CS>ICD9</PCM_PROBLEM_CS>
 </PROBLEM_MODULE>

мой файл привязки ( условиеBinding.xml )

<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="hl7.astm.greenccd.org"
    xml-mapping-metadata-complete="true">  
 <java-types>  
   <java-type name="Condition" >
           <xml-root-element name="PROBLEM_MODULE"  /> 
           <xml-type prop-order="diagnosisPriority problemDate problemType problemName problemCode ageAtOnset problemStatus comment"/>
           <java-attributes>
           <xml-element java-attribute="diagnosisPriority" xml-path="ID/text()" />
           <xml-element java-attribute="problemDate"  />
           <xml-element java-attribute="problemType" name="PROBLEM_TYPE" type="Cd"/>        
           <xml-element java-attribute="problemName"  />
           <xml-element java-attribute="problemCode"  />
           <xml-element java-attribute="ageAtOnset" xml-path="PCM_TREATING_PROVIDER_ID/text()" />
           <xml-element java-attribute="problemStatus" />
           <xml-element java-attribute="comment"  />
           </java-attributes>
            </java-type>

        <java-type name="Cd">
            <xml-type prop-order="code codeSystem displayName codeSystemName"/>
            <java-attributes>
                <xml-attribute java-attribute="code" xml-path="PR_ID/text()"/>
                <xml-attribute java-attribute="codeSystem" xml-path="PROBLEM_CODE/text()"/>
                <xml-attribute java-attribute="displayName" xml-path="PROBLEM_NAME/text()"/>
                <xml-attribute java-attribute="codeSystemName" xml-path="PCM_PROBLEM_CS/text()"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Основной код с привязкой и вводом xml:

 public static void main(String[] args) {

        try {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/conditions/exec/conditionsBinding.xml"));
         JAXBContext jc = JAXBContext.newInstance(new Class[] {Condition.class, Cd.class}, properties);
        Unmarshaller u = jc.createUnmarshaller();
        Condition conditionInput = (Condition) u.unmarshal( 
                       new File("src/conditions/exec/problems.xml")); 
    //Marshall Code
            properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/conditions/exec/binding.xml"));
            JAXBContext resultJC = JAXBContext.newInstance(new Class[] {Condition.class}, properties);

            Marshaller resultMarshaller = resultJC.createMarshaller();
            resultMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            resultMarshaller.marshal(conditionInput, System.out); 

Вывод сверху основного кода:

<Condition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <diagnosisPriority>91</diagnosisPriority>
   <problemType/>
   <ageAtOnset>23456</ageAtOnset>
</Condition>

ПРОБЛЕМА: При выполнениипривязка, тег

<problemType/>

выходит пустым, я пытаюсь связать Cd с problemType, поэтому вывод xml из problemType должен быть таким:

<problemType code="1223343" displayName="Asthma" codeSystem="23433.23232.23232" codeSystemName="ICD-9"/>

Посоветуйте, пожалуйста, что яотсутствует в файле привязки.

РЕДАКТИРОВАТЬ : файл binding.xml.Я использую этот файл, чтобы упорядочить имена элементов xml и имена переменных в объектах java:

<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="hl7.astm.greenccd.org" 
xml-mapping-metadata-complete="true">
<java-types>
    <java-type name="Condition" xml-accessor-type="FIELD">
        <xml-root-element name="Condition"/>
    </java-type>
  <java-type name="Cd" xml-accessor-type="FIELD">
        <xml-root-element name="problemType"/>
    </java-type>
</java-types>
</xml-bindings>

Примечание. Я проверил код без binding.xml, и он дал мне те же результаты с разнымиимена элементов.Код Main.java без binding.xml выглядит следующим образом:

public static void main(String[] args) {

        try {

    Map<String, Object> properties = new HashMap<String, Object>(1);
    properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/conditions/exec/conditionsBinding.xml"));
         JAXBContext jc = JAXBContext.newInstance(new Class[] {Condition.class, Cd.class}, properties);

        // create an Unmarshaller
        Unmarshaller u = jc.createUnmarshaller();
        Condition conditionInput = (Condition) u.unmarshal( 
                   new File("src/conditions/exec/problems.xml")); 


    Marshaller resultMarshaller = jc.createMarshaller();
    resultMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    resultMarshaller.marshal(conditionInput, System.out); 



    } catch (JAXBException je) {
        je.printStackTrace();
    } 


}  

Вывод без файла binding.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<PROBLEM_MODULE>    
 <ID>91</ID>
 <PROBLEM_TYPE/>    
 <TREATING_PROVIDER_ID>23456</TREATING_PROVIDER_ID>
</PROBLEM_MODULE>

Отображение имен классов / полей Java вФайл problem.xml выглядит следующим образом:

<PROBLEM_MODULE>
  <ID>91</ID> /* maps to class Condition: diagnosisPriority */
  <PR_ID>124</PR_ID> /* maps to class Cd: code */
  <PROBLEM_TYPE>T</PROBLEM_TYPE> /* class Condition: problemType - problemType is of type Cd.java - Cd.java is a list of attributes only
  <PROBLEM_NAME>Asthma</PROBLEM_NAME> /* maps to class Cd: displayName*/
  <PROBLEM_CODE>244.9</PROBLEM_CODE>/* maps to class Cd: codeSystem*/
  <PATIENT_AWARENESS>N</PATIENT_AWARENESS>
  <TREATING_PROVIDER_ID>23456</TREATING_PROVIDER_ID> /* maps to Condition: ageAtOnset */
  <PROBLEM_CS>ICD9</PCM_PROBLEM_CS> /* maps to class Cd: codeSystemName*/
 </PROBLEM_MODULE>

Далее Примечание в файле problem.xml, для:

<PROBLEM_TYPE>T</PROBLEM_TYPE> /* class Condition: problemType - problemType is of type Cd.java - Cd.java is a list of attributes only

В моем файле conditionBinding.xml, Problem_Type у меня закодирован следующим образом:

<xml-element java-attribute="problemType" name="PROBLEM_TYPE" type="Cd"/>

Причина, по которой я это сделал, состоит в том, что у Problem_Type нет корневого элемента или name = "some_field", я изначально пытался сделать это в conditionBinding.xml:

<xml-element java-attribute="problemType" type="Cd"/>

Когда я это сделал, у меня не было строки кода для problemType, поэтому я добавил name = "some_field", чтобы проверить, возможно, это может быть моей проблемой.Я следую за примерами в moxy wiki, но есть кое-что очевидное, чего мне не хватает, но я не могу точно определить это.

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:

После измененияв условиях conditionBinding.xml через ответ, представленный ниже, я смог получить тот же вывод xml.Однако problemType должен быть списком атрибутов, поэтому я изменил код следующим образом: условиеBinding.xml

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="hl7.astm.greenccd.org" xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="Condition">
            <xml-root-element name="PROBLEM_MODULE" />
            <xml-type
                prop-order="diagnosisPriority problemDate problemType problemName problemCode ageAtOnset problemStatus comment" />
            <java-attributes>
                <xml-element java-attribute="diagnosisPriority"
                    xml-path="ID/text()" />
                <xml-element java-attribute="problemDate" />
                <xml-element java-attribute="problemType" name="PROBLEM_TYPE"
                    xml-path="." />
                <xml-element java-attribute="problemName" />
                <xml-element java-attribute="problemCode" />
                <xml-element java-attribute="ageAtOnset" name="PCM_TREATING_PROVIDER_ID" />
                <xml-element java-attribute="problemStatus" />
                <xml-element java-attribute="comment" />
            </java-attributes>
        </java-type>

        <java-type name="Cd">
            <xml-type prop-order="code codeSystem displayName codeSystemName" />
            <java-attributes>
                <xml-attribute java-attribute="code" name="PR_ID" />
                <xml-attribute java-attribute="codeSystem" name="PROBLEM_CODE" />
                <xml-attribute java-attribute="displayName" name="PROBLEM_NAME" />
                <xml-attribute java-attribute="codeSystemName" name="PCM_PROBLEM_CS" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Вывод был выполнен следующим образом (пусто)тег problemType):

<?xml version="1.0" encoding="UTF-8"?>
<Condition>
   <diagnosisPriority>91</diagnosisPriority>
   <problemType />
   <ageAtOnset>23456</ageAtOnset>
</Condition>

Выдержка из Cd.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "cd", propOrder = {
    "originalText",
    "qualifier"
})

public class Cd {

    protected Object originalText;
    protected List<Qualifier> qualifier;

    @XmlAttribute(name = "code")
    @XmlSchemaType(name = "anySimpleType")
    protected String code;

    @XmlAttribute(name = "displayName")
    @XmlSchemaType(name = "anySimpleType")
    protected String displayName;

    @XmlAttribute(name = "codeSystem")
    @XmlSchemaType(name = "anySimpleType")
    protected String codeSystem;

    @XmlAttribute(name = "codeSystemName")
    @XmlSchemaType(name = "anySimpleType")
    protected String codeSystemName;

    @XmlAttribute(name = "nullFlavor")
    protected NullFlavorType nullFlavor;

На другом замечании я понимаю, что мне потребуется позже аннотировать problemCode, которыйэто также поле в Conditions.java AND типа Cd, но оно будет сопоставлено с различными именами элементов xml.Для чего потребуется еще один блок аннотации Cd.java в файле conditionBinding.xml.(Отображения не являются реальными, но они будут отражать что-то вроде следующего:

Псевдо условияBinding.xml :

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="hl7.astm.greenccd.org" xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="Condition">
            <xml-root-element name="PROBLEM_MODULE" />
            <xml-type
                prop-order="diagnosisPriority problemDate problemType problemName problemCode ageAtOnset problemStatus comment" />
            <java-attributes>
                <xml-element java-attribute="diagnosisPriority"
                    xml-path="ID/text()" />
                <xml-element java-attribute="problemDate" />
                <xml-element java-attribute="problemType" name="PROBLEM_TYPE"
                    xml-path="." />
                <xml-element java-attribute="problemName" />
                <xml-element java-attribute="problemCode" name="PROBLEM_CODE_PSEUDO"
                    xml-path="."/>
                <xml-element java-attribute="ageAtOnset" name="PCM_TREATING_PROVIDER_ID" />
                <xml-element java-attribute="problemStatus" />
                <xml-element java-attribute="comment" />
            </java-attributes>
        </java-type>
    <java-type name="Cd">
        <xml-type prop-order="code codeSystem displayName codeSystemName" />
        <java-attributes>
            <xml-element java-attribute="code" name="PR_ID" />
            <xml-element java-attribute="codeSystem" name="PROBLEM_CODE" />
            <xml-element java-attribute="displayName" name="PROBLEM_NAME" />
            <xml-element java-attribute="codeSystemName" name="PCM_PROBLEM_CS" />
        </java-attributes>
    </java-type>
     /* java-type name = Cd will be mapped to different xml elements for problemCode */
    <java-type name="Cd">
        <xml-type prop-order="code codeSystem displayName codeSystemName" />
        <java-attributes>
            <xml-element java-attribute="code" name="PR_ID_PSEUDO" />
            <xml-element java-attribute="codeSystem" name="PROBLEM_CODE_PSEUDO" />
            <xml-element java-attribute="displayName" name="PROBLEM_NAME_PSEUDO" />
            <xml-element java-attribute="codeSystemName" name="PCM_PROBLEM_CS_PSEUDO" />
        </java-attributes>
    </java-type>

</java-types>

Это делаетя думаю, что мой подход должен быть изменен (не просто в зависимости от привязки). Я читал руководство пользователя moxy на http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy. Я изучил и рассмотрел следующие варианты: JPA (с использованием SAX / DOM - встретиться впромежуточное отображение), xml-join-node и xml-adapter. Мне не совсем ясно, какой из этих вариантов (если таковые имеются) помог бы в моей проблеме, ваш совет эксперта высоко ценится.

1 Ответ

1 голос
/ 19 августа 2011

UPDATE

В вашем примере вы используете binding.xml для управления отображением при сортировке. В этом файле привязки вы установили xml-mapping-metadata-complete="true". Это указывает MOXy, что аннотации следует игнорировать и что файл привязки указывает полные метаданные. Если этот флаг установлен в false или не указан, то файл привязки используется для дополнения аннотаций.

binding.xml

Ниже я удалил xml-mapping-metadata-complete="true":

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="hl7.astm.greenccd.org">
    <java-types>
        <java-type name="Condition" xml-accessor-type="FIELD">
            <xml-root-element name="Condition" />
        </java-type>
        <java-type name="Cd" xml-accessor-type="FIELD">
            <xml-root-element name="problemType" />
        </java-type>
    </java-types>
</xml-bindings>

выход

Теперь данные problemType отображаются в виде атрибутов:

<?xml version="1.0" encoding="UTF-8"?>
<Condition>
   <diagnosisPriority>91</diagnosisPriority>
   <problemType code="124" displayName="Asthma" codeSystem="244.9" codeSystemName="ICD9"/>
</Condition>
<Ч />

Должно помочь следующее:

conditionsBinding.xml

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="hl7.astm.greenccd.org" xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="Condition">
            <xml-root-element name="PROBLEM_MODULE" />
            <xml-type
                prop-order="diagnosisPriority problemDate problemType problemName problemCode ageAtOnset problemStatus comment" />
            <java-attributes>
                <xml-element java-attribute="diagnosisPriority"
                    xml-path="ID/text()" />
                <xml-element java-attribute="problemDate" />
                <xml-element java-attribute="problemType" name="PROBLEM_TYPE"
                    xml-path="." />
                <xml-element java-attribute="problemName" />
                <xml-element java-attribute="problemCode" />
                <xml-element java-attribute="ageAtOnset" name="PCM_TREATING_PROVIDER_ID" />
                <xml-element java-attribute="problemStatus" />
                <xml-element java-attribute="comment" />
            </java-attributes>
        </java-type>

        <java-type name="Cd">
            <xml-type prop-order="code codeSystem displayName codeSystemName" />
            <java-attributes>
                <xml-element java-attribute="code" name="PR_ID" />
                <xml-element java-attribute="codeSystem" name="PROBLEM_CODE" />
                <xml-element java-attribute="displayName" name="PROBLEM_NAME" />
                <xml-element java-attribute="codeSystemName" name="PCM_PROBLEM_CS" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Когда я использую его с вашим кодом, я получаю:

<?xml version="1.0" encoding="UTF-8"?>
<Condition>
   <diagnosisPriority>91</diagnosisPriority>
   <problemType>
      <code>124</code>
      <codeSystem>244.9</codeSystem>
      <displayName>Asthma</displayName>
      <codeSystemName>ICD9</codeSystemName>
   </problemType>
</Condition>
...