1

我正在尝试解组我之前编组的 XML。

在未编组的结果中,我缺少元素,并且我得到的元素与输入 XML 的顺序不同。我创建了一个 afterUnmarshal() 侦听器,我在那里看到了元素,但在生成的 Java 对象中看不到。

XSD 的结构是这样的(例如,“扇出”节点可以包含另一组 processStep,因此可以深度嵌套(树)):

<xsd:element name="process">
        <xsd:annotation>
            <xsd:documentation>Integration Process</xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
            <xsd:sequence>
        <!-- more -->
                <xsd:element name="itinerary" type="lwis:itineraryType"/>
        <!-- more -->
        </xsd:complexType>
    </xsd:element>
    <xsd:complexType name="itineraryType">
        <xsd:sequence>
            <xsd:element name="step" type="lwis:stepType"/>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="step" type="lwis:stepType"/>
                <xsd:element name="fanout" type="lwis:fanoutType"/>
                <xsd:element name="decision">
                    <xsd:complexType>
                            <!-- snip.. -->
                    </xsd:complexType>
                </xsd:element>
            </xsd:choice>
        </xsd:sequence>
    </xsd:complexType>

我想顺序是由 SAX 解析器给出的,但我无法想象 SAX 解析器会无缘无故地改变顺序?目前,列表中的第一个元素是 XML 中的最后一个元素。列表中的第二个元素是 XML 中的第三个元素 - 它似乎是随机的..

谢谢你的帮助!

样本输入:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<process name="My.Process" description="My Process description" qualityOfService="AT_LEAST_ONCE" entryEndpoint="ENTRY.EP" xmlns="http://www.xxxxx.com/ns/yyyy">
    <faultEndpoint endpoint_ref="EXIT.EP"/>
    <rejectEndpoint endpoint_ref="EXIT.EP"/>
    <itinerary>
        <step name="Step 1" endpoint_ref="Step1.EP" type="SERVICE"/>
        <step name="Step2-CBRStep" endpoint_ref="Step2.EP" type="SERVICE"/>
        <decision name="Decision-nonameneeded">
            <option name="op1">
                <step name="Step 2A" endpoint_ref="Step2a.EP" type="SERVICE"/>
            </option>
            <option name="op2">
                <step name="Step 2B" endpoint_ref="Step2a.EP" type="SERVICE"/>
            </option>
        </decision>
        <step name="Step 3" endpoint_ref="Step3.EP" type="SERVICE"/>
        <fanout name="Fan1">
            <path>
                <step name="Step4A" endpoint_ref="Step4A.EP" type="SERVICE"/>
            </path>
            <path>
                <step name="Step4B" endpoint_ref="Step4B.EP" type="SERVICE"/>
                <step name="Step5" endpoint_ref="Step5.EP" type="SERVICE"/>
            </path>
        </fanout>
        <step name="Step6" endpoint_ref="Step6.EP" type="SERVICE"/>
    </itinerary>
</process>

目的:

Process Object has a field with itinerary of Type ItineraryType which:
step = StepType ("Step6" from XML)
stepOrFanoutOrDecision = ArrayList:
 item 0: ItineraryType$Decision ("Decision-nonameneeded" from XML)
   option 0: "op1" from XML
     step: "Step 2A" from XML
   option 1: "op2" from XML
     step: "Step 2B" from XML
 item 1: FanoutType ("Fan1" from XML)
     path 0: 
      step: Step4A
     path 1: 
      step: Step5

缺少步骤 1、Step2-CBRStep 和步骤 4B?

我在这里有行程的 toString() 输出:

com.x.ItineraryType@fe39ebf[step=com.x.StepType@28cb15bf[endpointRef=Step6.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step6, description=<null>], stepOrFanoutOrDecision={com.x.ItineraryType$Decision@2d00c385[option={com.x.ItineraryType$Decision$Option@d2467d8[step=com.x.StepType@511d9ca5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2A, description=<null>], stepOrFanoutOrDecision=<null>, name=op1],com.x.ItineraryType$Decision$Option@6f173e3d[step=com.x.StepType@5ef74fc5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2B, description=<null>], stepOrFanoutOrDecision=<null>, name=op2]}, name=Decision-nonameneeded, description=<null>],com.x.FanoutType@3e963f38[path={com.x.FanoutType$Path@7a1095a1[step=com.x.StepType@56cfbba2[endpointRef=Step4A.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step4A, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>],com.x.FanoutType$Path@6027b534[step=com.x.StepType@4ee99a3d[endpointRef=Step5.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step5, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>]}, name=Fan1, description=<null>]}]

我正在使用的 Ant 脚本:带有扩展 hashCode、toString 和 equals:

<?xml version="1.0" encoding="UTF-8"?>
<project name="RunningXjc" default="generate-sources" basedir=".">
    <description>Runs Xjc Binding Compiler</description>

    <target name="generate-sources">
        <taskdef name="xjc" classname="org.jvnet.jaxb2_commons.xjc.XJC2Task">
            <classpath>
                <fileset dir="buildLib/jaxb-ri-2.2.6/lib">
                    <include name="*" />
                </fileset>
                <fileset dir="buildLib/jaxb2-basics-dist-0.6.4/dist">
                    <include name="jaxb2-basics-ant-*.jar" />
                </fileset>
            </classpath>
        </taskdef>

        <!-- Generate the Java code for XSD -->
        <xjc destdir="${basedir}/target/generated-sources/xjc" extension="true">
            <arg
                line="
        -Xequals
        -XhashCode
        -XtoString
        -Xcopyable
        -Xmergeable" />
            <binding dir="${basedir}/src">
                <include name="**/*.xjb" />
            </binding>
            <schema dir="${basedir}/schema">
                <include name="processSlim.xsd" />
            </schema>
            <!-- Plugins -->
            <classpath>
                <fileset dir="${basedir}/buildLib/jaxb2-basics-dist-0.6.4">
                    <!-- JAXB2 Basics library -->
                    <include name="dist/jaxb2-basics-*.jar" />
                    <!-- JAXB2 Basics library dependencies -->
                    <include name="dist/jaxb2-basics-runtime-*.jar" />
                    <include name="dist/jaxb2-basics-tools-*.jar" />
                    <include name="lib/commons-beanutils-*.jar" />
                    <include name="lib/commons-lang-*.jar" />
                    <include name="lib/commons-logging-*.jar" />
                    <include name="lib/javaparser-*.jar" />
                    <include name="lib/annox-*.jar" />
                </fileset>
            </classpath>
        </xjc>
    </target>
</project>
4

1 回答 1

1

问题

从您的 XML 模式

下面是您的 XML 模式的一个片段。itineraryType包含一个序列,其中一个元素step可以出现在选择结构的内部和外部。

<xsd:complexType name="itineraryType">
    <xsd:sequence>
        <xsd:element name="step" type="lwis:stepType" />
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
            <xsd:element name="step" type="lwis:stepType" />
            <xsd:element name="fanout" type="lwis:fanoutType" />
            <xsd:element name="decision">
                <xsd:complexType>
                    <!-- snip.. -->
                </xsd:complexType>
            </xsd:element>
        </xsd:choice>
    </xsd:sequence>
</xsd:complexType>

行程类型

这导致step元素被映射到导致您的问题的两个不同属性。

public class ItineraryType {

    @XmlElement(required = true)
    protected StepType step;
    @XmlElements({
        @XmlElement(name = "step", type = StepType.class),
        @XmlElement(name = "fanout", type = FanoutType.class),
        @XmlElement(name = "decision", type = ItineraryType.Decision.class)
    })
    protected List<Object> stepOrFanoutOrDecision;

   ...
}

解决方案

您可以使用 JAXB XJC 工具中的简单绑定模式扩展来支持此用例。它将自动阻止step创建该属性。您可以通过如下外部绑定文档指定此内容:

绑定.xml

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    jxb:extensionBindingPrefixes="xjc"
    version="2.1">


    <jxb:globalBindings>
        <xjc:simple />
    </jxb:globalBindings>

</jxb:bindings>

XJC 呼叫

下面是如何在 XJC 调用中引用外部绑定文件。您还需要使用该-extension标志来启用要使用的 XJC 扩展。

xjc -extension -b bindings.xml schema.xsd 
于 2013-03-25T15:25:21.923 回答