2011-11-30 3 views
13

내가 이러한 버전 사용하고 자바 7에서 제공되는 JAXB 구현을 사용하여 일부 XML 파일을 처리하기 위해 노력하고있어 :JAXB 처리

501 ~ % xjc -version 
xjc 2.2.4 
502 ~ %java -version   
java version "1.7.0_01" 
Java(TM) SE Runtime Environment (build 1.7.0_01-b08) 
Java HotSpot(TM) Server VM (build 21.1-b02, mixed mode) 

XML 스키마의 문제 decalaration은 다음입니다 : 유형의 값 : 당신이 볼 수 있듯이

<xsd:complexType name="CategorizeType"> 
    <xsd:complexContent> 
     <xsd:extension base="se:FunctionType"> 
      <xsd:sequence> 
       <xsd:element ref="se:LookupValue"/> 
       <xsd:element ref="se:Value"/> 
       <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
        <xsd:element ref="se:Threshold"/> 
        <xsd:element ref="se:Value"/> 
       </xsd:sequence> 
       <xsd:element ref="se:Extension" minOccurs="0" /> 
      </xsd:sequence> 
      <xsd:attribute name="thresholdBelongsTo" 
        type="se:ThresholdBelongsToType" use="optional"/> 
     </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

하는 것은, 그 자체의이 개 명시 적으로 발행 수있다. 그러나 xjc를 사용하여 컴파일을 중단하지는 않습니다. 경우,

public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

불행하게도 :이 유형에 대해 생성 된 Java 클래스에서 봐 가지고 있다면, 나는 다음과 같은 방법을 사용하여

<xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
    <xsd:element ref="se:Threshold"/> 
    <xsd:element ref="se:Value"/> 
</xsd:sequence> 

의 요소를 검색 할 theoritically 가능하다는 것을 볼 수있다

<Categorize thresholdsBelongTo="succeeding" fallbackValue="0"> 
    <LookupValue> 
     <ns3:ValueReference>OUI_EEE92</ns3:ValueReference> 
    </LookupValue> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
    <Threshold>45.0</Threshold> 
    <Value>0.5</Value> 
    <Threshold>50.0</Threshold> 
    <Value>0.55</Value> 
    <Threshold>55.0</Threshold> 
    <Value>0.6</Value> 
    <Threshold>60.0</Threshold> 
    <Value>0.7</Value> 
    <Threshold>70.0</Threshold> 
    <Value>0.8</Value> 
    <Extension> 
     <ExtensionParameter name="method">MANUAL</ExtensionParameter> 
    </Extension> 
</Categorize> 

ㅁ : 나는 내가 단지 CategorizeType 인스턴스가 다음과 같이 정의된다 나의 xml 파일에 임계 값으로 등록 된 요소를 검색 할 수 있습니다, 목록의 요소를 얻으려고 목록을 검색 할 때 임계 값만 볼 수 있습니다.

내가 잘못 했습니까? Jaxb의 내부 한계입니까? 나는 XML 스키마를 변경할 수 없습니다

주 ...

편집 :

I했습니다 그냥 -v 옵션을 사용하여 xjc를 실행하고 나는 세계적으로 동일한 출력을 얻을 수 있습니다.

xjc -verbose se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/filter/2.0/filterCapabilities.xsd 

compiling a schema... 
[INFO] generating codee 
unknown location 

없이 : 상세으로

xjc se/2.0/All.xsd 
parsing a schema... 
[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 23 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/ows19115subset.xsd 

[WARNING] java.net.SocketException: Unexpected end of file from server 
    line 22 of file:/home/alexis/crap/SE-Schema-2.0/ows/2.0/owsExceptionReport.xsd 

compiling a schema... 

다음 출력은 생성 된 파일의 이름과 위치를 포함합니다.

이 xsd는 Java 6과 함께 제공되는 xjc로 컴파일 할 수 없다는 점을 잊어 버렸습니다. JAXB 2.1.10에서 마지막으로 시도되었습니다. 지금은이 동작을 재현 할 수 없습니다. 자바 7. 작업

EDIT2 : 의견 제안 난 그냥의 binginds을 사용자 정의하려고했습니다

. 내 바인딩 파일은 다음과 같다 :

가 첫 번째 값 인스턴스가 실제로

@XmlElement(name = "Value", required = true) 
protected ParameterValueType firstValue; 
@XmlElements({ 
    @XmlElement(name = "Threshold", type = LiteralType.class), 
    @XmlElement(name = "Value", type = ParameterValueType.class) 
}) 
protected List<Object> thresholdAndValue; 

public ParameterValueType getFirstValue() { 
    return firstValue; 
} 
public void setFirstValue(ParameterValueType value) { 
    this.firstValue = value; 
} 
public List<Object> getThresholdAndValue() { 
    if (thresholdAndValue == null) { 
     thresholdAndValue = new ArrayList<Object>(); 
    } 
    return this.thresholdAndValue; 
} 

불행하게도 자바 코드에서 firstValue 속성으로 대체됩니다

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" > 
    <jxb:bindings schemaLocation="schema.xsd" 
        node="//xsd:complexType[@name='CategorizeType']"> 
     <jxb:bindings 
        node="xsd:complexContent/xsd:extension/xsd:sequence/xsd:element[@ref='se:Value'][position()=1]"> 
      <jxb:property name="FirstValue"/> 
     </jxb:bindings> 
    </jxb:bindings> 
</jxb:bindings> 

, 난 여전히 같은 결과를 얻을 - 난 아직 할 수 없습니다 getThresholdAndValues ​​()에 의해 반환 된 목록의 내 값을 봅니다. 난 여전히 사용자 정의 방식 ...

+0

'getThresholdAndValue' 메소드의 주석은 무엇입니까? 흥미로운 부분이지 방법 본문이 아닙니다. – skaffman

+0

없음. 이 클래스에서 찾을 수있는 유일한 주석은 클래스와 해당 속성에 설정됩니다. 그들 중 누구도 메서드에 설정되어 있지 않습니다 ... – Agemen

+0

흥미로운 문제 - 전체 스키마를 게시 할 수 있습니까? – davidfrancis

답변

1

난 당신이 xjc를 실행하기 전에 스키마 정의에 복합 타입을 추가하는 XSLT 변환을 삽입 할 수 있습니다

  <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
       <xsd:element ref="se:Threshold"/> 
       <xsd:element ref="se:Value"/> 
      </xsd:sequence> 

주위에 복합 타입의 요소를 필요가 있다고 생각을 탐험거야?

+0

예, 해결책 일 수 있습니다. 전에 XSLT를 사용 해본 적이 없으므로 시간이 좀 걸립니다. 나는이 목록이 나의 문제의 핵심이며, 그것이 별도의 복잡한 유형으로 정의 되었다면 훨씬 더 간단했을 것이라고 생각했다. 그러나 XSLT에 익숙하지 않았으므로 사용하지는 않았습니다. XML의 편집을 사용자 정의 할 수 있으므로 (XML 자체를 만질 수는 없더라도) 시도해 보겠습니다. – Agemen

+0

내가 두려워하는 점은이 XSD를 사용하여 정의 된 파일에 변환을 적용하지 않아도된다는 것입니다. 결과적으로, 나는 어떤 중간 요소도없이 가치 문턱치의 목록을 읽을 수 있어야 할 것이다 ... – Agemen

3

업데이트 : 죄송합니다. 나는이 문제를 포기해야했으며, 그 중 하나를 사용할 수 없었습니다 (스키마를 변경할 수 있다면 더 쉽게 할 수 있습니다). Codehaus JAXB maven plugin을 사용하고있었습니다. 나는 내가 xjb 사용자 정의로 해결하려고 두 요소에 의한 갈등의 확신 : 그것은 전혀 영향을 미치지 않았다

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<jxb:bindings jxb:version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <jxb:bindings schemaLocation="../xsd/example.xsd" node="/xsd:schema"> 
     <jxb:schemaBindings> 
      <jxb:package name="com.example" /> 
      <jxb:nameXmlTransform> 
       <jxb:elementName suffix="Element"/> 
      </jxb:nameXmlTransform> 
     </jxb:schemaBindings> 
    </jxb:bindings> 
</jxb:bindings> 

. 나는 <jxb:typeName suffix="Element"/>을 시도하고, 모든 JAXB 클래스의 이름을 바꿨으므로 jxb:elementName 기능이있는 버그가 있다고 가정합니다.

원래의 게시물 :

나는이보고있다 그리고 나는 당신의 문제를 복제 할 수 있어요.

단순화하기 위해 스키마에 몇 가지 자유를 썼지 만 여전히 필수 요소가 포함되어 있습니다. 여기에 내가 사용했던 것입니다 :

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:se="http://com.example/example" 
     targetNamespace="http://com.example/example" 
    elementFormDefault="qualified"> 

    <xsd:element name="Categorize" type="se:CategorizeType" /> 

    <xsd:complexType name="FunctionType"> 
    </xsd:complexType> 

    <xsd:simpleType name="Value"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:simpleType name="Threshold"> 
     <xsd:restriction base="xsd:string"/> 
    </xsd:simpleType> 

    <xsd:complexType name="CategorizeType"> 
     <xsd:complexContent> 
      <xsd:extension base="se:FunctionType"> 
       <xsd:sequence> 
        <xsd:element name="Value" type="se:Value" /> 
        <xsd:sequence minOccurs="0" maxOccurs="unbounded"> 
         <xsd:element name="Threshold" type="se:Threshold" /> 
         <xsd:element name="Value" type="se:Value" /> 
        </xsd:sequence> 
       </xsd:sequence> 
      </xsd:extension> 
     </xsd:complexContent> 
    </xsd:complexType> 
</xsd:schema> 

내가/문제와 관련이없는 속성 모든 요소를 ​​삭제 한 대신 refname/type를 사용하여 제공된 스키마에서 누락 유형을 정의했다. 같은

내 생성 된 JAXB CategorizeType 클래스는 같습니다

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "CategorizeType", propOrder = { 
    "value", 
    "thresholdAndValue" 
}) 
public class CategorizeType 
    extends FunctionType 
{ 

    @XmlElement(name = "Value", required = true) 
    protected String value; 
    @XmlElementRefs({ 
     @XmlElementRef(name = "Value", 
      namespace = "http://com.example/example", type = JAXBElement.class), 
     @XmlElementRef(name = "Threshold", 
      namespace = "http://com.example/example", type = JAXBElement.class) 
    }) 
    protected List<JAXBElement<String>> thresholdAndValue; 

    ... 
} 

나는 당신의 XML을 언 마샬링, 내 Categorize.Value은 (대신 예상 0.3의) 0.8이며, 각 ThresholdAndValue의 값 (모든 Strings 내 경우)은 30.0, 40.0, 45.0입니다. 0.4, 0.45 등이 없습니다.

스키마에서 첫 번째 Value 요소를 제거한 다음 언 마샬하면 예상되는 모든 값을 얻게되므로 명확하게 충돌이 발생합니다.

그러나, 나는 마샬 다음 JAXB 설정을 사용하는 경우 :

ObjectFactory factory = new ObjectFactory(); 
CategorizeType catType = factory.createCategorizeType(); 
catType.setValue("0.3"); 
JAXBElement<String> thresh = factory.createCategorizeTypeThreshold("30.0"); 
JAXBElement<String> threshVal = factory.createCategorizeTypeValue("0.4"); 
JAXBElement<String> thresh2 = factory.createCategorizeTypeThreshold("40.0"); 
JAXBElement<String> threshVal2 = factory.createCategorizeTypeValue("0.45"); 
catType.getThresholdAndValue().add(thresh); 
catType.getThresholdAndValue().add(threshVal); 
catType.getThresholdAndValue().add(thresh2); 
catType.getThresholdAndValue().add(threshVal2); 
JAXBElement<CategorizeType> element = factory.createCategorize(catType); 
// marshall to XML here! 

내가 예상 출력을 얻을 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Categorize xmlns="http://com.example/example"> 
    <Value>0.3</Value> 
    <Threshold>30.0</Threshold> 
    <Value>0.4</Value> 
    <Threshold>40.0</Threshold> 
    <Value>0.45</Value> 
</Categorize> 

나는이에보고하겠습니다을!