另一个Jaxb绑定问题

时间:2011-08-17 17:47:01

标签: binding jaxb moxy

我想我终于缩小了我的一个问题。我正在使用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

我创建的类: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>

我的绑定文件( conditionsBinding.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>

主代码w / 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);
        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,因此来自problemType的xml输出应如下:

<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的代码,它给了我相同的结果w /不同的元素名称。没有binding.xml的Main.java代码如下:

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类/字段名称到problems.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>
在examples.xml文件中

进一步注意,用于:

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

在我的conditionsBinding.xml文件中,我的Problem_Type编码如下:

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

我这样做的原因是Problem_Type没有根元素或name =“some_field”,我最初尝试在conditionsBinding.xml中执行:

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

当我这样做时,我没有获得problemType的代码行,所以我添加了一个名称=“some_field”来测试可能是我的问题。我正在关注moxy wiki中的示例,但有一些显而易见的事情我不知道但我无法确定它。

其他编辑:

通过下面提供的答案更改了conditionsBinding.xml之后,我能够获得相同的xml输出。但是,problemType应该是属性列表,所以我将代码更改为以下内容: 的 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-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和Cd类型中的一个字段,但是将被映射到不同的xml元素名称。这将需要conditionBinding.xml文件中的另一个Cd.java注释块。 (映射不是真实的,但它会反映出如下内容:

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

这让我觉得我的方法需要调整(根据绑定而不是soley)。我正在阅读moxy用户指南 http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy。我研究过并考虑过以下几种选择: JPA(使用SAX / DOM - 在中间映射中相遇),xml-join-nodes和xml-adapter。我并不完全清楚哪些选项(如果有的话)会对我的问题有所帮助,我们非常感谢您的专业建议。

1 个答案:

答案 0 :(得分:1)

<强>更新

在您的示例中,您使用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>