JAXB Moxy - Вопрос о том, как аннотировать поле сложного типа xsd - PullRequest
1 голос
/ 12 августа 2011

Я начинаю с JaxB и использую реализацию Moxy. У меня есть отраслевой стандарт xsd, который я преобразовал в Java Object Model, используя Jaxb. Я дошел до аннотирования простых полей, таких как строка, целое число и дата.

Я искал, и мне нужно указать в правильном направлении, чтобы аннотировать следующее поле, представляющее собой сложный тип xsd, который имеет 4 атрибута и необязательный строковый элемент. Подмножество сгенерированного кода выглядит следующим образом:

Conditions.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "condition"
})
@XmlRootElement(name = "conditions")
public class Conditions {
protected List<Conditions.Condition> condition;

public List<Conditions.Condition> getCondition() {
    if (condition == null) {
        condition = new ArrayList<Conditions.Condition>();
    }
    return this.condition;
}

@XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {
            "problemDate",
            "problemType",
            "problemCode",
            "problemStatus",         
    })
    public static class Condition {

        protected IvlTs problemDate;
        //This is the field I need to annotate (problemType)
        protected Cd problemType;
        //The 2 below fields (problemCode, problemStatus) will also have to be annotated but I am just focusing on problemType for now
        protected Cd problemCode;
        protected Ce problemStatus

 public void setProblemDate(IvlTs value) {
            this.problemDate = value;
        }

 public void setProblemType(Cd value) {
            this.problemType = value;
        }
public void setProblemCode(Cd value) {
            this.problemCode = value;
        }
public void setProblemStatus(Ce value) {
            this.problemStatus = value;
        }
 //omitted getters
    }

Cd.java

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

public class Cd {

    protected Object originalText;

    @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;

//ommitted getters and setters

Класс Cd.java будет использоваться для ряда других классов, а не только в классе Conditions.java.

Мой вопрос, в частности, заключается в том, как мне аннотировать мои поля для problemType в Conditions.java, где problemType имеет 4 атрибута и один необязательный элемент.

Я не смогу напрямую комментировать Cd.java, так как ввод XML будет отличаться в зависимости от того, какой класс я реализую (выбор из 8 других классов, которые используют класс Cd.java). Существующие выше аннотации были автоматически сгенерированы Jaxb. Входные данные для xml для ConditionSjava problemType выглядят следующим образом:

<PROBLEM_MODULE>
      <code>24434</code> //Maps to protected String code in Cd.java;
      <codeName>ICD-9</codeName> //Maps to protected String codeSystem in Cd.java;
      <display>Asthma</display> //Maps to protected String displayName in Cd.java;
      <codeSystem>2.564.34343.222</codeSystem> // Maps to protected String codeSystemName in Cd.java;
</PROBLEM_MODULE>

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

****** UPDATE **** *** Решение Блейза сработало отлично, так как я тестировал его на другом проекте, который не так сложен. Таким образом, метод правильный, но есть кое-что, что я ошибаюсь с файлом метаданных. Я обновил файл Conditions.java выше, так как не указал подробности, которые могут повлиять на способ реализации файла метаданных.

Мой файл oxm.xml

<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="conditions.exec"
    xml-mapping-metadata-complete="true">
     <java-types>
        <java-type name="Conditions" xml-accessor-type="FIELD">
            <xml-root-element name="PROBLEM_MODULE"/>
        </java-type>
        <java-type name="Cd" xml-accessor-type="FIELD">
            <java-attributes>
            <xml-type prop-order="code codeSystem displayName codeSystemName"/>
                <xml-element java-attribute="codeSystem" name="codeName"/>
                <xml-element java-attribute="displayName" name="display"/>
                <xml-element java-attribute="codeSystemName" name="codeSystem"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

* Основной класс *

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/oxm.xml"));
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Conditions.class,Cd.class}, properties);

            // create an Unmarshaller
            Unmarshaller u = jc.createUnmarshaller();
            conditions.exec.Conditions InventoryInput = (conditions.exec.Conditions) u.unmarshal( 
                        new File("src/conditions/exec/problems.xml")); //input file



            // create a Marshaller and marshal to a file



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

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

1 Ответ

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

Вы можете использовать файл внешнего связывания EclipseLink JAXB (MOXy) , чтобы применить второе сопоставление к вашему классу:

oxm.xml

Одна вещь, которую я установил в этом файле: xml-mapping-metadata-complete="true", эта настройка говорит MOXy полностью игнорировать аннотации и просто использовать этот файл. По умолчанию файл OXM используется для дополнения аннотаций.

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum7043389"
    xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="Root2">
            <xml-root-element/>
        </java-type>
        <java-type name="Cd">
            <xml-type prop-order="code codeSystem displayName codeSystemName"/>
            <java-attributes>
                <xml-element java-attribute="codeSystem" name="codeName"/>
                <xml-element java-attribute="displayName" name="display"/>
                <xml-element java-attribute="codeSystemName" name="codeSystem"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Демо

Файл oxm.xml передается как свойство для создания JAXBContext. В приведенном ниже примере jc1 создается для классов, а jc2 создается для классов и oxm.xml

.
package forum7043389;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    public static void main(String[] args) throws Exception {
        Cd cd = new Cd();
        cd.setCode("24434");
        cd.setCodeSystem("ICD-9");
        cd.setDisplayName("Asthma");
        cd.setCodeSystemName("2.564.34343.222");

        JAXBContext jc1 = JAXBContext.newInstance(Root1.class);
        Marshaller marshaller1 = jc1.createMarshaller();
        marshaller1.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        Root1 root1 = new Root1();
        root1.setCd(cd);
        marshaller1.marshal(root1, System.out);

        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum7043389/oxm.xml");
        JAXBContext jc2 = JAXBContext.newInstance(new Class[] {Root2.class}, properties);
        Marshaller marshaller2 = jc2.createMarshaller();
        marshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        Root2 root2 = new Root2();
        root2.setCd(cd);
        marshaller2.marshal(root2, System.out);
    }

}

выход

Ниже приводится результат запуска демо-версии:

<?xml version="1.0" encoding="UTF-8"?>
<root1>
   <cd code="24434" displayName="Asthma" codeSystem="ICD-9" codeSystemName="2.564.34343.222"/>
</root1>
<?xml version="1.0" encoding="UTF-8"?>
<root2>
   <cd>
      <code>24434</code>
      <codeName>ICD-9</codeName>
      <display>Asthma</display>
      <codeSystem>2.564.34343.222</codeSystem>
   </cd>
</root2>

Cd

package forum7043389;

import javax.xml.bind.annotation.*;

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

    protected Object originalText;

    @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;

    public Object getOriginalText() {
        return originalText;
    }

    public void setOriginalText(Object originalText) {
        this.originalText = originalText;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public String getCodeSystem() {
        return codeSystem;
    }

    public void setCodeSystem(String codeSystem) {
        this.codeSystem = codeSystem;
    }

    public String getCodeSystemName() {
        return codeSystemName;
    }

    public void setCodeSystemName(String codeSystemName) {
        this.codeSystemName = codeSystemName;
    }

    public NullFlavorType getNullFlavor() {
        return nullFlavor;
    }

    public void setNullFlavor(NullFlavorType nullFlavor) {
        this.nullFlavor = nullFlavor;
    }

}

root1

package forum7043389;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Root1 {

    private Cd cd;

    public Cd getCd() {
        return cd;
    }

    public void setCd(Cd cd) {
        this.cd = cd;
    }

}

root2

package forum7043389;

public class Root2 {

    private Cd cd;

    public Cd getCd() {
        return cd;
    }

    public void setCd(Cd cd) {
        this.cd = cd;
    }

}

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

...