2011-11-30 63 views
13

我尝试过程中使用出货的Java 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> 

正如你所看到的,se有两个显式的出现:Type中的Value。但是,它不会停止使用xjc编译。如果我有这种类型生成的Java类一看,我可以看到,它是theoritically可以使用以下方法来检索的

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

元素:

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

不幸的是,如果我试图让列表的元素,我只能取回我的XML文件,其中CategorizeType实例定义如下注册门槛的元素:

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

瓦在检索列表中,我只能看到阈值。

我做错了什么?它是Jaxb的内在局限性吗?

请注意,我不能改变的XML架构...

编辑:

我刚刚与-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。现在我无法再现此行为,因为我现在使用Java 7的工作

EDIT2:

我只是尝试自订binginds,在意见提出。我绑定文件如下:

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

的第一个值实例是由firstValue属性在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; 
} 

不幸的是,我仍然能获得同样的结果 - 我仍然不能在由getThresholdAndValues()返回的列表中查看我的值。我还在探索定制的方式...

+0

getThresholdAndValue方法的注释是什么?这是有趣的部分,而不是方法体。 – skaffman

+0

无。我可以在课堂上找到唯一的注释,并在课堂上和属性上进行设置。他们都没有设置方法... – Agemen

+0

有趣的问题 - 请你可以发布完整的模式? – davidfrancis

回答

1

我认为你需要周围

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

一个complexType元素可以插入XSLT转换运行XJC之前的complexType添加到模式的定义?

+0

是的,这可能是一个解决方案。由于我以前从未使用XSLT,因此需要一些时间:-p。我已经确定这个清单是我的问题的关键,如果它是以单独的复杂类型定义的话,它会简单得多。但是因为我不习惯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> 

我已经删除/属性不相关的问题的任何元素,使用name/type代替ref,并定义的类型从提供的模式失踪。

我产生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.8(而不是预期的0.3),并且每个ThresholdAndValue的(值在所有Strings我案件)是30.0, 40.0, 45.00.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> 

我会继续寻找这个!

相关问题