2

我在将 java 对象序列化为 XML 时遇到问题。我的课程如下所示:

@Root(strict = false, name = "Detail")
public class ProductList {
    @ElementList(inline = true, entry = "Product")
    private List<Product> products;
}

@Root(strict = false)
public class Product {
    @Element(name = "ProductCode")
    private String productCode;
    @Element(name = "ProductPrice")
    private double productPrice;
    @Element(name = "Currency")
    private String currency;
    @Element(name = "ConversionRate")
    private int conversionRate;
    @Element(name = "ProductPoints", required = false)
    private int productPoints;
    @Element(name = "ProductCount", required = false)
    private int productCount;
    @Element(name = "ProductName", required = false)
    private String productName;
    @Element(name = "MinPrice", required = false)
    private double minPricet;
    @Element(name = "MaxPrice", required = false)
    private double maxPricet;
    @Element(name = "CanChangePrice", required = false)
    private String canChangePrice;
}

下面的 XML 是从服务器发送的,并且反序列化没有任何问题:

<?xml version="1.0" encoding="UTF-8"?>
<Detail>
  <Product>
    <ProductCode>0001</ProductCode>
    <ProductPrice>0.90</ProductPrice>
    <Currency>GEL</Currency>
    <ConversionRate>200</ConversionRate>
    <ProductName>Bread</ProductName>
    <MinPrice>0.9</MinPrice>
    <MaxPrice>0.9</MaxPrice>
    <CanChangePrice>N</CanChangePrice>
  </Product>
  <Product>
    ...
  </Product>
</Detail>

我尝试生成具有这种结构的 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<Detail>
  <Product>
    <ProductCode>0001</ProductCode>
    <ProductPrice>0.90</ProductPrice>
    <Currency>GEL</Currency>
    <ConversionRate>200</ConversionRate>
    <ProductPoints>180</ProductPoints>
    <ProductCount>1</ProductCount>
  </Product>
  <Product>
    ...
  </Product>
</Detail>

但我明白了:

<Detail>
   <Product>
      <ProductCode>0001</ProductCode>
      <ProductPrice>0.9</ProductPrice>
      <Currency>GEL</Currency>
      <ConversionRate>200</ConversionRate>
      <productPoints>180</productPoints>
      <ProductCount>1</ProductCount>
      <ProductName>Bread</ProductName>
      <MinPrice>0.9</MinPrice>
      <MaxPrice>0.9</MaxPrice>
      <CanChangePrice>N</CanChangePrice>
   </Product>
   <Product>
      ...
   </Product>
</Detail>

标签<ProductName>, <MinPrice>, <MaxPrice>,<CanChangePrice>不得包含在序列化的 XML 中。

有什么方法可以告诉框架在序列化时不要包含特定的标签\变量?

4

3 回答 3

2

The problem

Your class members are not initialized to null and so required=false has not the effect of not serializing them.

ints are serialized by org.simpleframework.xml.transform.IntegerTransform. The write(Integer) method of this class is simple:

public String write(Integer value) {
   return value.toString();
}

As you can see, simple autoboxing is used.

  1. Your primitive int is initialized to 0 by the constructor.
  2. It is boxed into an Integer.
  3. The String value of this Integer is "0" which is not null.

Solution

Use Integer, not int for your class members.

Edit

If you don't want to serialize a member, don't annotate it with @Element. Simple is not about 'generating' XML but about mapping instances to/from XML. Every member you want to map needs an annotation. Every member with an annotation will be mapped.

于 2013-10-19T19:50:43.603 回答
0

我的解决方案非常难看。我为 XML 序列化创建了另一个类,它包含原始类中的每个字段,除了我想在 XML 中省略的字段。

于 2013-11-13T15:36:38.913 回答
0

您可以使用转换器覆盖默认序列化机制以自定义输出。例如,您提供的将是:

public class CustomProductConverter implements Converter<Product> {

    private void createProductPropertyNode(OutputNode productNode, String propertyName, String value) throws Exception {
        productNode.getChild(propertyName).setValue(value);
    }

    private void createProductPropertyNode(OutputNode productNode, String propertyName, int value) throws Exception {
        createProductPropertyNode(productNode, propertyName, String.valueOf(value));
    }

    private void createProductPropertyNode(OutputNode productNode, String propertyName, double value) throws Exception {
        createProductPropertyNode(productNode, propertyName, String.valueOf(value));
    }

    @Override
    public Product read(InputNode inputNode) throws Exception {
        throw new UnsupportedOperationException();
    }

    @Override
    public void write(OutputNode outputNode, Product product) throws Exception {
        createProductPropertyNode(outputNode, "ProductCode"   , product.getProductCode());
        createProductPropertyNode(outputNode, "ProductPrice"  , product.getProductPrice());
        createProductPropertyNode(outputNode, "Currency"      , product.getCurrency());
        createProductPropertyNode(outputNode, "ConversionRate", product.getConversionRate());
        createProductPropertyNode(outputNode, "ProductPoints" , product.getProductPoints());
        createProductPropertyNode(outputNode, "ProductCount"  , product.getProductCount());

        outputNode.commit();
    }
}

然后使用RegistryStrategy进行序列化:

Registry registry = new Registry();
registry.bind(Product.class, CustomProductConverter.class);

Strategy strategy = new RegistryStrategy(registry);
Serializer serializer = new Persister(strategy);

// serialize your object with serializer

优点:您可以使用不同的转换器动态序列化相同的对象并获得不同的输出,而无需修改模型类。

缺点:在复杂模型的情况下,转换器中会有很多类似的代码。

于 2017-08-16T13:29:08.750 回答