6

所以这是我的问题。我得到了一个 XSD,我生成的 XML 文件应该遵守该 XSD。我使用org.apache.cxf.cxf-xjc-pluginmaven 插件和外部绑定文件生成源代码。但是当我尝试编组我的对象时,生成的 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>

有没有办法以干净的方式解决这个问题?

我宁愿不要为每个单独totalDigitsfractionDigits组合编写多个适配器。由于 XSD 可能会发生变化,我想保持生成的源代码不变。

4

4 回答 4

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>

了解更多信息

于 2013-02-13T10:47:58.717 回答
1

例如,我创建了一些特殊的 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 位小数适配器做同样的事情。

于 2019-01-28T11:45:26.967 回答
0

如果您可以将 XSD 更改为使用此处precisionDecimal记录的类型,您也许可以使用设置为相同值的和方面。minScalemaxScale

于 2013-02-13T08:20:57.813 回答
0

我对保持尾随零可能获得什么感到困惑。

如果保留尾随零非常重要,则使用字符串值而不是数字并使用属性来指定其宽度和小数。

在任何情况下,尾随零都不会影响使用这些值中的任何一个的计算,并且您能够呈现它们的唯一方法是将结果转换为字符串并自己填充。如需帮助,您可能希望查看...

CXF 客户端 SOAP 消息格式

于 2014-01-22T22:00:58.557 回答