2011-11-30 39 views
13

Tôi đang cố gắng để xử lý một số file XML bằng cách sử dụng thực hiện JAXB vận chuyển trong Java 7. Tôi đang sử dụng các phiên bản này:JAXB xử lý chuỗi XML

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) 

Các decalaration có vấn đề trong lược đồ XML như sau :

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

Như bạn có thể thấy, có hai lần xuất hiện rõ ràng của se: Giá trị trong Loại. Tuy nhiên, nó không dừng việc biên dịch bằng cách sử dụng xjc. Và nếu tôi có một cái nhìn trong lớp Java được tạo ra cho loại hình này, tôi có thể thấy rằng nó là theoritically thể lấy các yếu tố của

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

sử dụng phương pháp sau đây:

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

Thật không may, nếu tôi cố gắng để có được các yếu tố của danh sách, tôi chỉ có thể lấy các yếu tố đăng ký là ngưỡng trong file xml của tôi, nơi dụ CategorizeType được định nghĩa như sau:

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

Wh vi truy xuất danh sách, tôi chỉ có thể thấy giá trị Ngưỡng.

Tôi có làm gì sai không? Nó là một giới hạn bên trong của Jaxb?

Lưu ý rằng tôi không thể thay đổi lược đồ XML ...

EDIT:

Tôi đã chỉ cần chạy XJC với các tùy chọn -v, và tôi có được trên toàn cầu đầu ra tương tự. Với tính cách rườm rà:

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 

Nếu không có nó:

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... 

Các đầu ra sau đây chỉ chứa tên và vị trí của các tập tin được tạo ra.

Tôi đã quên nói rằng xsd này không thể được biên dịch với xjc được gửi đi với Java 6. Lần thử cuối cùng đã được thực hiện với JAXB 2.1.10. Tôi không thể tạo lại hành vi này ngay bây giờ, như tôi bây giờ làm việc với Java 7.

EDIT2:

Tôi vừa cố gắng tùy chỉnh các bingind, như được đề xuất trong các nhận xét. tập ràng buộc của tôi là như sau:

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

Thể hiện giá trị đầu tiên thực sự là thay thế bằng một thuộc tính firstValue trong mã Java

@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; 
} 

Thật không may, tôi vẫn có được kết quả tương tự - Tôi vẫn không thể xem giá trị của tôi trong danh sách được trả về bởi getThresholdAndValues ​​(). Tôi vẫn đang tìm hiểu cách tùy biến ...

+0

Các chú thích trên phương thức 'getThresholdAndValue' là gì? Đó là phần thú vị, không phải là thân phương pháp. – skaffman

+0

Không có. Các chú thích duy nhất tôi có thể tìm thấy trong lớp này được đặt trên lớp và trên các thuộc tính của nó. Không ai trong số họ được thiết lập trên một phương pháp ... – Agemen

+0

Vấn đề thú vị - xin vui lòng bạn có thể đăng lược đồ đầy đủ? – davidfrancis

Trả lời

1

tôi nghĩ rằng bạn cần một yếu tố complexType xung quanh

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

Bạn có thể chèn một biến đổi XSLT để thêm một complexType định nghĩa giản đồ trước khi chạy XJC?

+0

Vâng, đó có thể là một giải pháp. Vì tôi chưa bao giờ sử dụng XSLT trước đây, nó sẽ đưa tôi một thời gian :-p. Tôi đã xác định rằng danh sách này là chìa khóa của vấn đề của tôi, và rằng nó sẽ đơn giản hơn nhiều nếu nó đã được định nghĩa trong một kiểu phức tạp riêng biệt. Nhưng vì tôi không quen với XSLT, tôi đã không nghĩ đến việc sử dụng nó. Tôi sẽ thử nó, vì tôi tự do tùy chỉnh việc biên dịch XML (ngay cả khi tôi không thể chạm vào chính XML). – Agemen

+0

Điều tôi sợ là, tôi không muốn áp dụng bất kỳ phép chuyển đổi nào cho các tệp được định nghĩa bằng XSD này. Do đó, tôi sẽ phải có khả năng đọc danh sách ngưỡng giá trị, không có bất kỳ phần tử trung gian nào ... – Agemen

3

Cập nhật: Xin lỗi tôi đã từ bỏ điều này, tôi không thể làm việc đó (nó sẽ dễ dàng hơn nhiều nếu bạn có thể thay đổi lược đồ của mình!). Tôi đã sử dụng Codehaus JAXB maven plugin. Tôi khá chắc chắn rằng đó là một cuộc xung đột gây ra bởi hai Value yếu tố, mà tôi đã cố gắng để sửa chữa với một tùy 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> 

Nó đã hoàn toàn không có hiệu lực. Tôi đã thử <jxb:typeName suffix="Element"/>, và nó đổi tên tất cả các lớp JAXB, vì vậy tôi giả sử có một lỗi với tính năng jxb:elementName.

Original Post:

Tôi đã nhìn vào điều này và tôi có thể tái tạo vấn đề của bạn.

Tôi mất một vài quyền tự do với lược đồ của bạn để đơn giản hóa mọi thứ, nhưng nó vẫn chứa các yếu tố thiết yếu. Dưới đây là những gì tôi đã sử dụng:

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

Tôi đã gỡ bỏ bất kỳ phần tử/thuộc tính không liên quan đến vấn đề này, sử dụng name/type thay vì ref, và xác định các loại mất tích từ giản đồ mà bạn cung cấp.

tạo lớp JAXB CategorizeType tôi trông như thế:

@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; 

    ... 
} 

Khi tôi unmarshall XML của bạn, Categorize.Value của tôi là 0.8 (thay vì dự kiến ​​0.3), và các giá trị của mỗi ThresholdAndValue (tất cả Strings trong tôi trường hợp) là 30.0, 40.0, 45.0, v.v. Thiếu 0.4, 0.45, v.v.

Khi tôi xóa phần tử Value đầu tiên khỏi lược đồ và sau đó unmarshall, tôi nhận được tất cả các giá trị mong đợi, vì vậy chắc chắn có xung đột!

Tuy nhiên, khi tôi marshall bằng cách sử dụng thiết lập sau 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! 

tôi nhận được kết quả mong muốn:

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

tôi sẽ tiếp tục tìm kiếm thành này!

Các vấn đề liên quan