我正在尝试使用 Java 7 中附带的 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 模式中有问题的声明如下:
<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:Value。但是,它不会停止使用 xjc 进行编译。如果我看一下为此类型生成的 Java 类,我可以看到理论上可以检索
的元素 <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。
编辑2:
我刚刚尝试按照评论中的建议自定义 binginds。我的绑定(bind)文件如下:
<?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 代码中的 firstValue 属性替换
@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() 返回的列表中看到我的值。我还在摸索自定义方式...
最佳答案
更新:对不起,我不得不放弃这个,我也无法让它工作(如果你能改变你的架构会容易得多!)。我正在使用 Codehaus JAXB maven plugin .我很确定这是由两个 Value 元素引起的冲突,我试图通过 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.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>
我会继续调查的!
关于java - XML 序列的 JAXB 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8326162/