XStream - 挑战向子元素添加属性
XStream - Challenge adding attribute to child element
我在向子元素添加属性以编写 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);
}
}
测试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(.. .) 在测试 class 中产生以下 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 来完成这类任务。在我在网上找到的任何示例中,添加属性的元素都映射到 class,而在我的例子中,我要添加属性的元素本身位于映射的 class 中到 "parent" 元素。我浏览了 xstream 网站,但未在此处找到与我的目标直接相关的任何示例。不幸的是,JAXB 不是一个选项,因为我使用的是不支持它的 openjdk 12。我不知道 openjdk 12 中是否内置了 XML 文档编写器(我还是那个版本的新手)。我想我想不通的是如何以某种方式 "associate" TXLifeRequest POJO 中的特定子元素以及我想要添加的属性。请原谅我对代码的错误使用,其一,在 hierarchicalStreamWriter.addAttribute("tc", "1203"); 语句中添加的字符串文字 TransTypeAttributeConverter 我确定是在错误的上下文或位置。如果有人能对此有所了解,将不胜感激。谢谢!
抱歉,我还应该补充一点,我考虑过的其他选项是为每个元素编写 POJO(我意识到这可能是极端且低效的),或者将 POJO 中的子元素映射到内部 class 这样它实际上变成了它自己的 parent 元素。
我最终使用 java DOM 解析器作为解决方案,它允许我直接在元素 TransType 上设置属性。如果碰巧有人 知道如何在 XStream 中解决这个问题,我仍然有兴趣知道。干杯。
我在向子元素添加属性以编写 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);
}
}
测试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(.. .) 在测试 class 中产生以下 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 来完成这类任务。在我在网上找到的任何示例中,添加属性的元素都映射到 class,而在我的例子中,我要添加属性的元素本身位于映射的 class 中到 "parent" 元素。我浏览了 xstream 网站,但未在此处找到与我的目标直接相关的任何示例。不幸的是,JAXB 不是一个选项,因为我使用的是不支持它的 openjdk 12。我不知道 openjdk 12 中是否内置了 XML 文档编写器(我还是那个版本的新手)。我想我想不通的是如何以某种方式 "associate" TXLifeRequest POJO 中的特定子元素以及我想要添加的属性。请原谅我对代码的错误使用,其一,在 hierarchicalStreamWriter.addAttribute("tc", "1203"); 语句中添加的字符串文字 TransTypeAttributeConverter 我确定是在错误的上下文或位置。如果有人能对此有所了解,将不胜感激。谢谢!
抱歉,我还应该补充一点,我考虑过的其他选项是为每个元素编写 POJO(我意识到这可能是极端且低效的),或者将 POJO 中的子元素映射到内部 class 这样它实际上变成了它自己的 parent 元素。
我最终使用 java DOM 解析器作为解决方案,它允许我直接在元素 TransType 上设置属性。如果碰巧有人 知道如何在 XStream 中解决这个问题,我仍然有兴趣知道。干杯。