Java XML序列的JAXB处理

Java XML序列的JAXB处理,java,jaxb,Java,Jaxb,我正在尝试使用Java7中提供的JAXB实现来处理一些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) XML模式中存在问题的十

我正在尝试使用Java7中提供的JAXB实现来处理一些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)
XML模式中存在问题的十分位如下:

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

如您所见,类型中有两个显式出现se:Value。但是,它不会停止使用xjc的编译。如果我查看一下为这种类型生成的Java类,我会发现从理论上可以检索


使用以下方法:

公共列表getThresholdAndValue(){ if(thresholdAndValue==null){ thresholdAndValue=新的ArrayList(); } 返回此.thresholdAndValue; } 不幸的是,如果我尝试获取列表中的元素,我只能检索xml文件中注册为阈值的元素,其中CategorizeType实例定义如下:


OUI_EEE92
0.3
30
0.4
40
0.45
45
0.5
50
0.55
55
0.6
60
0.7
70
0.8
手册
检索列表时,我只能看到阈值

我做错什么了吗?这是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不能用Java6附带的xjc编译。最后一次尝试是使用JAXB2.1.10。我现在无法重现这种行为,因为我现在正在使用Java7

编辑2:

正如评论中所建议的,我刚刚尝试过定制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>

在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;
}
@xmlement(name=“Value”,required=true)
受保护的参数ValueType firstValue;
@XmlElements({
@XmlElement(name=“Threshold”,type=LiteralType.class),
@XmlElement(name=“Value”,type=ParameterValueType.class)
})
保护列表阈值和值;
公共参数ValueType getFirstValue(){
返回第一个值;
}
public void setFirstValue(参数值类型值){
this.firstValue=值;
}
公共列表getThresholdAndValue(){
if(thresholdAndValue==null){
thresholdAndValue=新的ArrayList();
}
返回此.thresholdAndValue;
}

不幸的是,我仍然得到相同的结果-我仍然无法在GetThresholdValues()返回的列表中看到我的值。我仍在探索定制方式…

我认为您需要一个complexType元素

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


在运行xjc之前,是否可以插入XSLT转换以向模式定义中添加ComplexType?

更新:很抱歉,我不得不放弃这一点,我也无法让它工作(如果您可以更改模式,会更容易!)。我在用电话。我很确定这是由两个值元素引起的冲突,我尝试用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>
我已删除了与问题无关的任何元素/属性,使用了
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 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>

0.3
30
0.4
40
0.45

我会继续调查的

getthresholdandwalue
方法上的注释是什么?这是有趣的部分,而不是方法体。无。在这个类中我能找到的唯一注释是在类及其属性上设置的。没有一个是在方法上设置的…有趣的问题-请发布完整的模式好吗?PS您可以临时更改模式只是为了进行实验-这可能是名称空间问题?我想知道使用绑定定制将
元素映射到两个不同的java类是否会有所帮助?是的,这可能是一个解决办法。因为我以前从未使用过XSLT,所以这需要一些时间。我已经确定这个列表是我问题的关键,如果它是在一个单独的复杂类型中定义的话,它会简单得多。但由于我不习惯XSLT,所以我不想使用它。我会尝试一下,因为我可以自由地自定义XML的编译(即使我不能接触XML本身)。不过,我担心的是,我不想对使用这个XSD定义的文件应用任何转换。因此,我必须能够读取阈值列表,而不需要任何中间元素。。。
<?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>