MOXy XPath解组的元素为空。

huangapple go评论102阅读模式
英文:

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

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;groupId&gt;org.example&lt;/groupId&gt;
    &lt;artifactId&gt;BPMN-Marshaller&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;properties&gt;
        &lt;maven.compiler.source&gt;1.8&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;1.8&lt;/maven.compiler.target&gt;
    &lt;/properties&gt;
    &lt;repositories&gt;&lt;repository&gt;
        &lt;id&gt;EclipseLink Repo&lt;/id&gt;
        &lt;url&gt;http://download.eclipse.org/rt/eclipselink/maven.repo&lt;/url&gt;
        &lt;name&gt;EclipseLink Repo&lt;/name&gt;
    &lt;/repository&gt;&lt;/repositories&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.eclipse.persistence&lt;/groupId&gt;
            &lt;artifactId&gt;org.eclipse.persistence.moxy&lt;/artifactId&gt;
            &lt;version&gt;3.0.0-M1&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
            &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
            &lt;version&gt;2.5.3&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;!-- Runtime, com.sun.xml.bind module --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.glassfish.jaxb&lt;/groupId&gt;
            &lt;artifactId&gt;jaxb-runtime&lt;/artifactId&gt;
            &lt;version&gt;2.3.2&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;jakarta.xml.bind&lt;/groupId&gt;
            &lt;artifactId&gt;jakarta.xml.bind-api&lt;/artifactId&gt;
            &lt;version&gt;2.3.2&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

&lt;/project&gt;

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=&quot;http://www.omg.org/spec/BPMN/20100524/MODEL&quot;, elementFormDefault=XmlNsForm.QUALIFIED, xmlns = {@XmlNs(prefix=&quot;bpmn&quot;, namespaceURI=&quot;http://www.omg.org/spec/BPMN/20100524/MODEL&quot;)
        ,@XmlNs(prefix = &quot;camunda&quot;, namespaceURI = &quot;http://camunda.org/schema/1.0/bpmn&quot;)})

package bpmn;

import javax.xml.bind.annotation.*;

xml file snippet

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;bpmn:definitions xmlns:bpmn=&quot;http://www.omg.org/spec/BPMN/20100524/MODEL&quot; xmlns:bpmndi=&quot;http://www.omg.org/spec/BPMN/20100524/DI&quot; xmlns:dc=&quot;http://www.omg.org/spec/DD/20100524/DC&quot; xmlns:camunda=&quot;http://camunda.org/schema/1.0/bpmn&quot; xmlns:di=&quot;http://www.omg.org/spec/DD/20100524/DI&quot; id=&quot;Definitions_13d3a6z&quot; targetNamespace=&quot;http://bpmn.io/schema/bpmn&quot; exporter=&quot;Camunda Modeler&quot; exporterVersion=&quot;4.1.1&quot;&gt;
  &lt;bpmn:process id=&quot;Process_1tovjba&quot; isExecutable=&quot;true&quot;&gt;
    &lt;bpmn:startEvent id=&quot;StartEvent_1&quot;&gt;
      &lt;bpmn:outgoing&gt;Flow_06i118e&lt;/bpmn:outgoing&gt;
    &lt;/bpmn:startEvent&gt;
    &lt;bpmn:task id=&quot;Activity_1d3friu&quot; name=&quot;Task 1&quot;&gt;
      &lt;bpmn:extensionElements&gt;
        &lt;camunda:properties&gt;
          &lt;camunda:property name=&quot;start_date&quot; value=&quot;01-04-2018&quot; /&gt;
          &lt;camunda:property name=&quot;duration&quot; value=&quot;5&quot; /&gt;
        &lt;/camunda:properties&gt;
      &lt;/bpmn:extensionElements&gt;
      &lt;bpmn:incoming&gt;Flow_06i118e&lt;/bpmn:incoming&gt;
      &lt;bpmn:outgoing&gt;Flow_0linmbs&lt;/bpmn:outgoing&gt;
    &lt;/bpmn:task&gt;

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 &quot;Definitions [id23=&quot; + id + &quot;, process=23499999999999999&quot; + process + &quot;]&quot;;
    }

}

Process Class

public class Process {

    private String id;
    private List&lt;Task&gt; taskList;
    private List&lt;SequenceFlow&gt; sequenceFlowList;

    public Process(){};
    public Process(String id, List&lt;Task&gt; taskList, List&lt;SequenceFlow&gt; 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 = &quot;task&quot;)
    public List&lt;Task&gt; getTaskList() {
        return taskList;
    }

    public void setTaskList(List&lt;Task&gt; taskList) {
        this.taskList = taskList;
    }

    @XmlElement(name = &quot;sequenceFlow&quot;)
    public List&lt;SequenceFlow&gt; getSequenceFlowList() {
        return sequenceFlowList;
    }

    public void setSequenceFlowList(List&lt;SequenceFlow&gt; sequenceFlowList) {
        this.sequenceFlowList = sequenceFlowList;
    }
}

Task Class

public class Task {

    private String id;
    private String name;
    private List&lt;Property&gt; propertyList;

    public Task(){}
    public Task(String id, String name, List&lt;Property&gt; propertyList){
        super();
        this.id = id;
        this.name = name;
        this.propertyList = propertyList;
    }

    @XmlAttribute
    @JsonProperty(&quot;text&quot;)
    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 = &quot;property&quot;)
    @XmlPath(&quot;bpmn:extensionElements/camunda:properties/camunda:property&quot;)
    public List&lt;Property&gt; getPropertyList() {
        return propertyList;
    }

    public void setPropertyList(List&lt;Property&gt; 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(&quot;process.bpmn&quot;);
            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();
        }


    }
}

Project Structure

答案1

得分: 1

我对你的方法做了以下更改,我能够从你的XML文件中访问durationstart_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:

        &lt;dependency&gt;
            &lt;groupId&gt;com.sun.activation&lt;/groupId&gt;
            &lt;artifactId&gt;javax.activation&lt;/artifactId&gt;
            &lt;version&gt;1.2.0&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;!-- 
             Use 2.3.1 below to prevent &quot;illegal 
             reflective access operation&quot; warnings.
        --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;javax.xml.bind&lt;/groupId&gt;
            &lt;artifactId&gt;jaxb-api&lt;/artifactId&gt;
            &lt;version&gt;2.3.1&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;com.sun.xml.bind&lt;/groupId&gt;
            &lt;artifactId&gt;jaxb-core&lt;/artifactId&gt;
            &lt;version&gt;2.3.0.1&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;com.sun.xml.bind&lt;/groupId&gt;
            &lt;artifactId&gt;jaxb-impl&lt;/artifactId&gt;
            &lt;version&gt;2.3.1&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.eclipse.persistence&lt;/groupId&gt;
            &lt;artifactId&gt;eclipselink&lt;/artifactId&gt;
            &lt;version&gt;2.7.6&lt;/version&gt;
        &lt;/dependency&gt;

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

    &lt;!-- to copy the jaxb.properties file to its class package: --&gt;
    &lt;build&gt;
        &lt;resources&gt;
            &lt;resource&gt;
                &lt;directory&gt;src/main/java&lt;/directory&gt;
                &lt;excludes&gt;
                    &lt;exclude&gt;**/*.java&lt;/exclude&gt;
                &lt;/excludes&gt;
            &lt;/resource&gt;
        &lt;/resources&gt;
    &lt;/build&gt;

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(&quot;EclipseLink MOXy&quot;);
        } else if(METRO_JAXB_CONTEXT.equals(jaxbContextImpl)) {
            System.out.println(&quot;Metro&quot;);
        } else {
            System.out.println(&quot;Other&quot;);
        }
    }

I modified the code to loop through the properties data, to explicitly print the final properties values:

List&lt;Property&gt; props = definitions.getProcess().getTaskList().get(0).getPropertyList();
props.forEach(prop -&gt; {
    System.out.println(prop.getName() + &quot; - &quot; + prop.getValue());
});
//System.out.println(definitions.getProcess().getTaskList().get(0).getPropertyList());

The resulting output is:

EclipseLink MOXy
start_date - 01-04-2018
duration - 5

huangapple
  • 本文由 发表于 2020年8月18日 20:41:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63468873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定