我有以下XML:
<patient>
<name>Mr. Sick</name>
<report>
<paragraph><bold>Conclusion</bold>text...</paragraph>
</report>
</patient>
我想将此转换为类似患者的实例,如下所示:
Class Patient {
String name = "Mr. Sick";
String report = "<paragraph><bold>Conclusion</bold>text...</paragraph>";
}
是否可以使用XStream仅转换部分XML并将报告字段保持为XML格式?怎么办呢?
答案 0 :(得分:4)
我通过创建转换器实现来解决它,如here所述。我对此问题的解决方案如下:
Patient.java
public class Patient {
String name;
Report report;
}
Report.java
public class Report {
public String report;
}
转换器for XStream的实现
public class ReportConverter implements Converter {
@Override
public boolean canConvert(Class classs) {
System.out.println("canConvert: " + classs.getName());
return classs.equals(Report.class);
}
@Override
public void marshal(Object value, HierarchicalStreamWriter writer,
MarshallingContext context) {
// not used in this example
}
// goes recursive through all the nodes in <report>
String getNodeAsText(HierarchicalStreamReader reader) {
String result;
result = "<" + reader.getNodeName() + ">" + reader.getValue();
while (reader.hasMoreChildren() ) {
reader.moveDown();
result += getNodeAsText(reader);
reader.moveUp();
result += reader.getValue();
}
result += "</" + reader.getNodeName() + ">";
return result;
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
Report xReport = new Report();
xReport.report = reader.getValue();
while (reader.hasMoreChildren() ) {
reader.moveDown();
xReport.report += getNodeAsText(reader);
reader.moveUp();
xReport.report += reader.getValue();
}
return xReport;
}
}
使用XStream转换器的示例
XStream xStream = new XStream();
xStream.registerConverter(new ReportConverter());
xStream.alias("patient", Patient.class);
xStream.alias("report", Report.class);
String xml = "<patient><name>Mr. Sick</name><report><paragraph>" +
"some text here<bold>Conclusion</bold>text...</paragraph>" +
"<sdf>hello world</sdf></report></patient>";
Patient patient = (Patient)xStream.fromXML(xml);
System.out.println("patient.name: " + patient.name);
System.out.println("patient.report: " + patient.report.report);
输出
patient: Mr. Sick
patient.report: <paragraph>some text here<bold>Conclusion</bold>text...
...</paragraph><sdf>hello world</sdf>
答案 1 :(得分:3)
我没有得到问题的答案,但我建议一个可能有帮助的替代方案。
您可能应该转义report
字段的内容。这将帮助您避免无效的xml,这在解组时可能会非常有问题。
这是一种简单的方法(使用来自apache org.apache.commons.lang.StringEscapeUtils的公共libray):
class Patient {
String name = "Mr. Sick";
String report = StringEscapeUtils.escapeHtml(
"<paragraph><bold>Conclusion</bold>text...</paragraph>");
// report = "<paragraph><bold>Conclusion</bold>text...</paragraph>"
}
答案 2 :(得分:2)
更好的getNodeAsText()版本,包含每个节点的属性:
private String getNodeAsText(HierarchicalStreamReader reader) {
StringBuilder str = new StringBuilder();
str.append("<")
.append(reader.getNodeName());
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeName(i);
String value = reader.getAttribute(i);
str.append(" ")
.append(name)
.append("=\"")
.append(value)
.append("\"");
}
str.append(">")
.append(reader.getValue());
while (reader.hasMoreChildren()) {
reader.moveDown();
str.append(getNodeAsText(reader));
reader.moveUp();
str.append(reader.getValue());
}
str.append("</")
.append(reader.getNodeName())
.append(">");
return str.toString();
}
StringBuilder str = new StringBuilder();
str.append("<")
.append(reader.getNodeName());
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeName(i);
String value = reader.getAttribute(i);
str.append(" ")
.append(name)
.append("=\"")
.append(value)
.append("\"");
}
str.append(">")
.append(reader.getValue());
while (reader.hasMoreChildren()) {
reader.moveDown();
str.append(getNodeAsText(reader));
reader.moveUp();
str.append(reader.getValue());
}
str.append("</")
.append(reader.getNodeName())
.append(">");
return str.toString();