【问题标题】:XStream - Challenge adding attribute to child elementXStream - 向子元素添加属性的挑战
【发布时间】:2020-01-13 19:01:15
【问题描述】:

我在为子元素添加属性以编写 XML 文件时遇到了困难。至少对我来说,挑战在于元素映射到的 POJO 与父元素相关联。我希望 XML 输出如下所示:

<TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TXLifeRequest>
    <TransRefGUID>906D67C1-CC4D-11CF-91FB-444554540000</TransRefGUID>
    <TransType tc="1203"></TransType>
    <TransExeDate>2020-01-06</TransExeDate>
    <TransExeTime>09:30:00</TransExeTime>
    ...multiple other parent and child elements..
  </TXLifeRequest>
</TXLife>

这是我需要在其中添加属性的 TransType 元素(如上所示)。

POJOS:

@XStreamAlias("TXLife")
public class TXLife {

    @XStreamAsAttribute
    private String version;

    @XStreamAsAttribute
    final String xmlns = "http://ACORD.org/Standards/Life/2";

    @XStreamAsAttribute
    @XStreamAlias("xmlns:xsi")
    final String xlink="http://www.w3.org/2001/XMLSchema-instance";

    @XStreamImplicit
    private List<TXLifeRequest> transListings = new ArrayList<TXLifeRequest>();

    public TXLife() {
        super();
    }
...getters and setters
@XStreamAlias("TXLifeRequest")
public class TXLifeRequest {

    @XStreamAlias("TransRefGUID")
    private String transRefGUID;

    @XStreamAlias("TransType")
    private String transType;

    @XStreamAlias("TransExeDate")
    private String transExeDate;

    @XStreamAlias("TransExeTime")
    private String transExeTime;

    public TXLifeRequest(String transRefGUID, String transType, String transExeDate, String transExeTime) {
        this.transRefGUID = transRefGUID;
        this.transType = transType;
        this.transExeDate = transExeDate;
        this.transExeTime = transExeTime;
    }
...getters and setters

转换器:

public class TransTypeAttributeConverter implements Converter {

    @Override
    public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
        TXLifeRequest txLifeRequest = (TXLifeRequest) o;
        hierarchicalStreamWriter.addAttribute("tc", "1203");
        hierarchicalStreamWriter.setValue("");
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
        return null;
    }

    @Override
    public boolean canConvert(Class type) {
        return type.equals(TXLifeRequest.class);
    }
}

测试类:

public class TestXMLOutput {

    public static void main(String[] args) throws UnsupportedEncodingException {

        TestXMLOutput testXMLOutput = new TestXMLOutput();

        TXLife txLife = new TXLife();
        txLife.setVersion("2.42.00");
        txLife.add(new TXLifeRequest("906D67C1-CC4D-11CF-91FB-444554540000", "",
                "2020-01-06", "09:30:00"));

        testXMLOutput.testConvertAndWriteXMLToFile(txLife);

    }

    public void testConvertAndWriteXMLToFile(TXLife txLife) throws UnsupportedEncodingException {
        XStream xstream = new XStream(new StaxDriver());
        xstream.processAnnotations(TXLife.class);
        xstream.alias("TXLife", TXLife.class);
        xstream.processAnnotations(TXLifeRequest.class);
        xstream.alias("TXLifeRequest", TXLifeRequest.class);

        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream("CITS_BoB/src/test/java/txlife.xml"));
        } catch (IOException e) {
            System.out.println("IOException Occurred: " + e.getMessage());
        }

        xstream.addImplicitCollection(TXLife.class, "transListings");
        //xstream.registerConverter(new TransTypeAttributeConverter());

        xstream.marshal(txLife, new PrettyPrintWriter(
                new OutputStreamWriter(bos, StandardCharsets.UTF_8)));


    }
}

我发现在测试类中同时运行 xstream.addImplicitCollection(...)xstream.registerConverter(...) 会产生以下 XML 输出:

<TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TXLifeRequest tc="1203"></TXLifeRequest>
</TXLife>

我确定我误解或完全错过了如何正确使用 xstream 来完成此类任务。在我在网上找到的任何示例中,添加属性的元素都映射到一个类,而在我的情况下,我想要添加属性的元素本身就是一个映射到“父”元素的类。我浏览了xstream 网站,但没有找到与我的目标直接相关的任何示例。不幸的是,JAXB 不是一个选项,因为我使用的是不支持它的 openjdk 12。我不知道 openjdk 12 中是否内置了 XML 文档编写器(我还是那个版本的新手)。我想我想不通的是如何以某种方式将 TXLifeRequest POJO 中的特定子元素与我想要添加到它的属性“关联”起来。请原谅我对代码的错误使用,一是在 TransTypeAttributeConverter 中的 hierarchicalStreamWriter.addAttribute("tc", "1203"); 语句中添加的字符串文字我是肯定是在错误的上下文或地方。如果有人能对此有所了解,将不胜感激。谢谢!

对不起,我还应该补充一点,我考虑过的其他选项是为每个元素编写 POJO(我意识到这可能是极端且低效的),或者将 POJO 中的子元素映射到内部类,这样它实际上成为它自己的 parent 元素。

【问题讨论】:

    标签: xstream openjdk-12


    【解决方案1】:

    我最终使用了 java DOM 解析器作为解决方案,它允许我直接在元素 TransType 上设置属性。如果碰巧有人确实知道如何在 XStream 中解决这个问题,我仍然很想知道。干杯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多