英文:
MOXy XPath unmarshalling Element is null
问题
我正在尝试使用XPath将camunda:property元素解组为List,以跳过不必要的包装元素。不幸的是,我的propertyList始终为null。这位于Task类中。非常感谢任何帮助。
编辑#1:
我按照以下链接进行了操作,这些链接应该有助于解决我的问题,但不幸的是没有成功。
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html,这是官方指南。显然,在maven pom.xml文件中存在一些挑战。我怀疑问题出在pom文件中。
我遵循了这个指南https://www.javacodegeeks.com/2012/07/eclipselink-moxy-as-jaxb-provider.html,但仍然无法使其工作。
pom.xml文件
<!-- 在这里是您的 pom.xml 内容 -->
jaxb.properties文件与我的java类位于相同的包和文件夹中(请参见附带的名称为“Project Structure”的图像)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
package-info.java文件
/* 在这里是您的 package-info.java 内容 */
xml文件片段
<!-- 在这里是您的 xml 文件片段 -->
Definitions类
/* 在这里是您的 Definitions 类内容 */
Process类
/* 在这里是您的 Process 类内容 */
Task类
/* 在这里是您的 Task 类内容 */
Property类
/* 在这里是您的 Property 类内容 */
Main类
/* 在这里是您的 Main 类内容 */
英文:
Im trying to unmarshall the camunda:property elements into a List using XPath to skip the unnecessary wrapper elements. Unfortunately my propertyList is always null. This is located in the Task Class. Any help would be greatly appreciated.
Edit#1:
I followed the following links who were supposed to help with my problem unfortunately without success. http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html which is the official guide. Apparently there are some challenges with the maven pom.xml file. I suspect that the problem lies inside the pom file.
I followed this guide https://www.javacodegeeks.com/2012/07/eclipselink-moxy-as-jaxb-provider.html but still did not get it to work.
pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>BPMN-Marshaller</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories><repository>
<id>EclipseLink Repo</id>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
<name>EclipseLink Repo</name>
</repository></repositories>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>3.0.0-M1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
</project>
jaxb.properties file in the same package and folder as my java classes(see attached image with name "Project Structure")
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
package-info.java file
@XmlSchema(namespace="http://www.omg.org/spec/BPMN/20100524/MODEL", elementFormDefault=XmlNsForm.QUALIFIED, xmlns = {@XmlNs(prefix="bpmn", namespaceURI="http://www.omg.org/spec/BPMN/20100524/MODEL")
,@XmlNs(prefix = "camunda", namespaceURI = "http://camunda.org/schema/1.0/bpmn")})
package bpmn;
import javax.xml.bind.annotation.*;
xml file snippet
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_13d3a6z" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.1.1">
<bpmn:process id="Process_1tovjba" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_06i118e</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:task id="Activity_1d3friu" name="Task 1">
<bpmn:extensionElements>
<camunda:properties>
<camunda:property name="start_date" value="01-04-2018" />
<camunda:property name="duration" value="5" />
</camunda:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_06i118e</bpmn:incoming>
<bpmn:outgoing>Flow_0linmbs</bpmn:outgoing>
</bpmn:task>
Definitions Class
@XmlRootElement
public class Definitions {
private String id;
private Process process;
public Definitions(){};
public Definitions(String id, Process process){
super();
this.id = id;
this.process = process;
}
@XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
@Override
public String toString(){
return "Definitions [id23=" + id + ", process=23499999999999999" + process + "]";
}
}
Process Class
public class Process {
private String id;
private List<Task> taskList;
private List<SequenceFlow> sequenceFlowList;
public Process(){};
public Process(String id, List<Task> taskList, List<SequenceFlow> sequenceFlowList){
super();
this.id = id;
this.taskList = taskList;
this.sequenceFlowList = sequenceFlowList;
}
@XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement(name = "task")
public List<Task> getTaskList() {
return taskList;
}
public void setTaskList(List<Task> taskList) {
this.taskList = taskList;
}
@XmlElement(name = "sequenceFlow")
public List<SequenceFlow> getSequenceFlowList() {
return sequenceFlowList;
}
public void setSequenceFlowList(List<SequenceFlow> sequenceFlowList) {
this.sequenceFlowList = sequenceFlowList;
}
}
Task Class
public class Task {
private String id;
private String name;
private List<Property> propertyList;
public Task(){}
public Task(String id, String name, List<Property> propertyList){
super();
this.id = id;
this.name = name;
this.propertyList = propertyList;
}
@XmlAttribute
@JsonProperty("text")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement(name = "property")
@XmlPath("bpmn:extensionElements/camunda:properties/camunda:property")
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
Property Class
public class Property {
private String name;
private String value;
public Property(){}
public Property(String name, String value) {
super();
this.name = name;
this.value = value;
}
@XmlAttribute
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAttribute
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Main Class
public class XMLToObject {
public static void main(String[] args) {
try {
File file = new File("process.bpmn");
JAXBContext jaxbContext = JAXBContext.newInstance(Definitions.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Definitions definitions = (Definitions) jaxbUnmarshaller.unmarshal(file);
System.out.println(definitions.getProcess().getTaskList().get(0).getPropertyList());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
答案1
得分: 1
我对你的方法做了以下更改,我能够从你的XML文件中访问duration
和start_date
属性的数据。
顺便说一下,我正在使用OpenJDK 14。但这种方法也可以在版本8上运行正常。
我正在使用的POM具有以下依赖关系:
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<!--
请使用2.3.1以避免“非法反射访问操作”警告。
-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.6</version>
</dependency>
(为了这个测试,我跳过了Jackson依赖项。)
我还在我的POM末尾添加了以下部分,以处理属性文件:
<!-- 复制jaxb.properties文件到其类包中的位置: -->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
这确保属性文件与其相关的类文件一起部署到正确的位置。
我添加了用于检查正在使用的JAXB提供程序的代码 - 只是作为积极的确认:
private void checkProvider() throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Definitions.class);
String jaxbContextImpl = jc.getClass().getName();
if(MOXY_JAXB_CONTEXT.equals(jaxbContextImpl)) {
System.out.println("EclipseLink MOXy");
} else if(METRO_JAXB_CONTEXT.equals(jaxbContextImpl)) {
System.out.println("Metro");
} else {
System.out.println("Other");
}
}
我修改了代码以循环遍历属性数据,以显式打印最终的属性值:
List<Property> props = definitions.getProcess().getTaskList().get(0).getPropertyList();
props.forEach(prop -> {
System.out.println(prop.getName() + " - " + prop.getValue());
});
结果输出为:
EclipseLink MOXy
start_date - 01-04-2018
duration - 5
英文:
I made the following changes to your approach, and I am able to access the duration
and start_date
properties data from your XML file.
I am using OpenJDK 14, by the way. But this approach runs OK using version 8 also.
The POM I am using has the following dependencies:
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<!--
Use 2.3.1 below to prevent "illegal
reflective access operation" warnings.
-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.6</version>
</dependency>
(I skipped the Jackson dependency just for this test.)
I also added the following section at the end of my POM, to handle the properties file:
<!-- to copy the jaxb.properties file to its class package: -->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
This ensures the properties file is deployed to the correct location with its related class files.
I added the code to check for which JAXB provider is being used - just as a positive confirmation:
private void checkProvider() throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Definitions.class);
String jaxbContextImpl = jc.getClass().getName();
if(MOXY_JAXB_CONTEXT.equals(jaxbContextImpl)) {
System.out.println("EclipseLink MOXy");
} else if(METRO_JAXB_CONTEXT.equals(jaxbContextImpl)) {
System.out.println("Metro");
} else {
System.out.println("Other");
}
}
I modified the code to loop through the properties data, to explicitly print the final properties values:
List<Property> props = definitions.getProcess().getTaskList().get(0).getPropertyList();
props.forEach(prop -> {
System.out.println(prop.getName() + " - " + prop.getValue());
});
//System.out.println(definitions.getProcess().getTaskList().get(0).getPropertyList());
The resulting output is:
EclipseLink MOXy
start_date - 01-04-2018
duration - 5
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论