我想我终于缩小了我的问题之一。我正在使用带有 Moxy 实现的 Jaxb。我在绑定文件中使用 Xpath 表示法。我没有得到想要的结果。
原来的 jaxb 生成的类是重度嵌套的,为了测试,我把代码精简到了 Condition.java 下面。
条件.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 类提供的摘录如下
问题.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>
带有绑定和 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 链接到问题类型,所以问题类型的 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 的代码,它给了我相同的结果,但元素名称不同。没有 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 类/字段名称到问题.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>
在 questions.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"/>
当我这样做时,我没有得到问题类型的代码行,所以我添加了一个 name="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>
输出如下(空的问题类型标签):
<?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;
另一方面,我意识到我需要稍后注释问题代码,这也是条件.java 中的一个字段,类型为 Cd,但将映射到不同的 xml 元素名称。这将需要在 conditionsBinding.xml 文件中添加另一个 Cd.java 注释块。(映射不是真实的,但它会反映如下内容:
伪条件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>
这让我觉得我的方法需要调整(不是单独取决于绑定)。我正在阅读 http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy上的 moxy 用户指南。我研究并考虑了以下选项:JPA(使用 SAX/DOM - 在中间映射中相遇)、xml-join-nodes 和 xml-adapter。我不完全清楚这些选项中的哪一个(如果有的话)对我的问题有帮助,非常感谢您的专家建议。