2013-03-23 2 views
1

이전에 정렬 한 XML을 비 정렬 화하려고합니다.JAXB Unmarshal - 요소가 누락되어 있고 요소가 순서대로 정렬되지 않았습니다.

비 정렬화된 결과에서 요소가 누락되었습니다. 그리고 얻는 요소가 입력 XML과 동일한 순서가 아닙니다. afterUnmarshal() 리스너를 만들었으므로 거기에 요소가 있지만 결과 Java 객체에는 표시되지 않습니다.

XSD는 (a 'fanout' 노드, 예를 들어, processSteps 다른 세트를 포함 할 수 있으므로 깊이 트리 (중첩 될 수있다))과 같이 구성된다 :

<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, 스텝 2 및 스텝 CBRStep-4B 누락? , toString를 확장 해시 코드와 동일 : 내가 사용

[email protected][[email protected][endpointRef=Step6.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step6, description=<null>], stepOrFanoutOrDecision={[email protected][option={[email protected][[email protected][endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2A, description=<null>], stepOrFanoutOrDecision=<null>, name=op1],[email protected][[email protected][endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2B, description=<null>], stepOrFanoutOrDecision=<null>, name=op2]}, name=Decision-nonameneeded, description=<null>],[email protected][path={[email protected][[email protected][endpointRef=Step4A.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step4A, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>],[email protected][[email protected][endpointRef=Step5.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step5, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>]}, name=Fan1, description=<null>]}] 

개미 스크립트 :

는 여기 여정의 toString() 출력이

<?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> 
+0

해당 JAXB 객체는 어떻게 생겼습니까? –

+0

추가 정보 추가 - 관심을 끌기를 바랬습니다 :) 블로그에서 일부 항목을 읽었지만 찾고있는 것을 찾을 수 없었습니다 .. – PhilW

+0

XML 스키마에서 모델을 생성 했습니까? –

답변

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> 

ItineraryType

이이 문제를 일으키는 두 개의 서로 다른 속성에 매핑 할 수있는 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 도구에서 simple binding mode 확장을 사용할 수 있습니다. 자동으로 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 통화에서 참조하는 방법이다. XJC 확장을 사용하려면 -extension 플래그도 사용해야합니다.

xjc -extension -b bindings.xml schema.xsd 
+0

감사합니다. JAXB? 본질적으로 동일한 노드를 포함 할 수있는 3 가지 노드가있는 트리이지만 각 분기의 첫 번째 노드는 'step'유형이어야합니다. 어떻게 하시겠습니까? (다른 방법으로 자유롭게 선택할 수 있습니다. 프레임 워크 등)) – PhilW

+0

@PhilW - XJC 확장 기능으로 어떻게 처리 할 수 ​​있는지에 대한 답변을 업데이트했습니다. –

+1

고마워요! 시도해 보았고 코드를 읽고 쓰기가 쉬워졌습니다. XSD에 따라 유효하지 않은 객체를 생성 할 수도 있습니다 (프로세스 일정의 첫 번째 항목은 단계 유형이어야하며 의사 결정 또는 팬 아웃이 아니어야합니다.) 나는이 사실을 알고있을 것이라고 확신하지만, 다른 사람들의 관심사. 다시 한 번 감사드립니다. 며칠 내 작업을 저장했습니다. – PhilW

관련 문제