JAXB Moxy-有关如何注释 xsd 复杂类型字段的问题

发布于 2024-11-29 20:23:55 字数 5457 浏览 1 评论 0原文

我正在开始使用 JaxB 并使用 Moxy 实现。我有一个行业标准 xsd,我使用 Jaxb 将其转换为 Java 对象模型。我已经能够注释简单的字段,如字符串、整数和日期。

我一直在搜索,需要指向正确的方向来注释以下字段,该字段是一个 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 类。

我的问题特别是如何在 Conditions.java 中注释 ProblemType 的字段,其中 ProblemType 有 4 个属性和一个可选元素。

我将无法直接注释 Cd.java,因为 xml 输入将根据我实现的类而有所不同(选择使用 Cd.java 类的 8 个其他类)。上面现有的注释是由 Jaxb 自动生成的。 Conditions.java ProblemType 的 xml 输入如下:

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

请告知我需要在哪里澄清我的问题。最终我请求资源或教程来帮助我解决这个问题。

******更新*< /em>****** 当我在另一个不那么复杂的项目上测试布莱斯的解决方案时,它运行得非常好。因此,该方法是正确的,但我在元数据文件中出现了错误。我更新了上面的 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();
        } 

I am getting started with JaxB and am using the Moxy implementation. I have an industry standard xsd that I converted to Java Object Model using Jaxb. I have gotten as far as annotating simple fields like string,integer and date.

I have been searching and need to be pointed in the right direction to annotate the following field which is a xsd complex type which has 4 attributes and an optional string element. A subset of the generated code is as follows:

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

The Cd.java class will be used for a number of other classes, not only in the Conditions.java class.

My question in particular is how would I annotate my fields for problemType in Conditions.java, where problemType has 4 attributes and one optional element.

I will not be able to directly annotate Cd.java as the xml input will differ depending on what class I am implementing (choice of 8 other classes that use Cd.java class). The existing annotations above were auto-generated by Jaxb The xml input for the Conditions.java problemType is as follows:

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

Please advise where I need to clarify my question. Ultimately I am requesting resources or tutorial to help me through this.

******UPDATE*******
Blaise's solution worked perfectly as I tested it on another project that is not as complex. Thus, the method is right, but there is something that I am getting wrong with the metadata file. I updated the Conditions.java file above, as I left out details that may effect the way I need to implement the metadata file.

My oxm.xml file

<?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>

*Main Class*

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();
        } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鸢与 2024-12-06 20:23:55

您可以利用 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;
    }

}

了解更多信息

You can leverage EclipseLink JAXB (MOXy)'s external binding file to apply a second mapping to your class:

oxm.xml

One thing that I have set in this file is xml-mapping-metadata-complete="true", this setting tells MOXy to ignore the annotations completely and just use this file. By default the OXM file is used to supplement the annotations.

<?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>

Demo

The oxm.xml file is passed in as a property to create the JAXBContext. In the example below jc1 is created on the classes and jc2 is created on the classes and 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);
    }

}

Output

The following is the output from running the demo:

<?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;
    }

}

For More Information

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文