所以这是我的问题。我给了一个我生成的XML文件应符合的XSD。使用org.apache.cxf.cxf-xjc-plugin
maven插件和外部绑定文件,我生成源代码。但是当我尝试编组我的对象时,生成的XML不符合我的要求。
我的XSD包含以下内容:
<xsd:element maxOccurs="1" minOccurs="0" name="amount">
<xsd:simpleType>
<xsd:restriction base="xsd:decimal">
<xsd:totalDigits value="13" />
<xsd:fractionDigits value="2" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
...
<xsd:element maxOccurs="1" minOccurs="0" name="rate">
<xsd:simpleType>
<xsd:restriction base="xsd:decimal">
<xsd:totalDigits value="8" />
<xsd:fractionDigits value="5" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
生成的XML片段如下所示:
<amount>109.5</amount>
...
<rate>10.25</rate>
虽然我期待它:
<amount>109.50</amount>
...
<rate>10.25000</rate>
有没有办法以干净的方式解决这个问题?
我不希望为每个totalDigits
,fractionDigits
组合编写多个适配器。由于XSD可能会发生变化,我想保持生成的源代码不变。
答案 0 :(得分:6)
您需要在此用例中使用XmlAdapter
。下面是一个示例绑定文件,可帮助您生成它们。该逻辑将包含在DecimalFormatter
类中,该类包含所有不同格式的方法。
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
<jxb:bindings schemaLocation="schema.xsd">
<jxb:bindings node="//xs:element[@name='amount']">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="java.math.BigDecimal"
parseMethod="org.example.DecimalFormatter.parseDecimal"
printMethod="org.example.DecimalFormatter.printDecimal_2Places" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
<jxb:bindings node="//xs:element[@name='rate']">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="java.math.BigDecimal"
parseMethod="org.example.DecimalFormatter.parseDecimal"
printMethod="org.example.DecimalFormatter.printDecimal_5Places" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
了解更多信息
答案 1 :(得分:0)
如果您可以更改XSD以使用记录为here的precisionDecimal
类型,则可以将minScale
和maxScale
构面设置为相同的值。< / p>
答案 2 :(得分:0)
我对通过保持尾随零可能获得的东西感到困惑。
如果尾随零保留很重要,则使用字符串值而不是数字,并使用属性指定其宽度和小数。
在任何情况下,尾随零都不会影响使用任何这些值的计算,并且您能够呈现它们的唯一方法是将结果转换为字符串并自行填充。对于一些帮助,你可能想要看到......
答案 3 :(得分:0)
例如,我已经创建了一些特殊的XmlAdapter
public class BigDecimal8PlaceAdapter extends XmlAdapter<String, BigDecimal> {
@Override
public String marshal(BigDecimal v) throws Exception {
DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
otherSymbols.setDecimalSeparator('.');
DecimalFormat df = new DecimalFormat("#0.00000000",otherSymbols);
return df.format(v);
}
@Override
public BigDecimal unmarshal(String v) throws Exception {
Double d = Double.valueOf(v);
return BigDecimal.valueOf(d);
}
}
然后在属性中添加XmlAdapter:
@XmlElement(name = "rate", required = true)
@XmlJavaTypeAdapter(BigDecimal8PlaceAdapter.class)
protected BigDecimal rate;
然后,使用2个小数的adapeter做同样的事情。