【问题标题】:XStream: Keep parts of the XML as XMLXStream:将部分 XML 保留为 XML
【发布时间】:2011-11-07 12:35:35
【问题描述】:

我有以下 XML:

<patient>
    <name>Mr. Sick</name>
    <report>
        <paragraph><bold>Conclusion</bold>text...</paragraph>
    </report>
</patient>

我想将其转换为 Patient 类的实例,如下所示:

Class Patient {
    String name = "Mr. Sick";
    String report = "<paragraph><bold>Conclusion</bold>text...</paragraph>";
}

是否可以使用 XStream 仅转换部分 XML 并将报告字段保持为 XML 格式?怎么办?

【问题讨论】:

  • 您可以使用 JAXB 实现(Metro、EclipseLink MOXy、Apache JaxMe)和@XmlAnyElement 注释:blog.bdoughan.com/2011/04/…
  • 谢谢。尽管我没有使用此解决方案,但它有助于找到答案。结合 XStream 对 @XmlAnyElement 的搜索为我提供了足够的信息让我重新开始。我发布了我对这个问题的回答。

标签: java xml xstream


【解决方案1】:

包含每个节点属性的更好的 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();

}

【讨论】:

    【解决方案2】:

    here 所述,我通过创建转换器实现解决了这个问题。我对这个问题的解决方法如下:

    Patient.java

    public class Patient {
        String name;
        Report report;
    }
    

    报告.java

    public class Report {
        public String report;
    }
    

    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>
    

    【讨论】:

      【解决方案3】:

      我没有所问问题的答案,但我建议可能有帮助的替代方案。

      您可能应该转义 report 字段的内容。这将帮助您避免在解组时可能会出现问题的无效 xml。

      这是一种简单的方法(使用来自 apache org.apache.commons.lang.StringEscapeUtils 的公共库):

      class Patient {
         String name = "Mr. Sick";
         String report = StringEscapeUtils.escapeHtml(
               "<paragraph><bold>Conclusion</bold>text...</paragraph>");
      
        // report = "&lt;paragraph&gt;&lt;bold&gt;Conclusion&lt;/bold&gt;text...&lt;/paragraph&gt;"
      }
      

      【讨论】:

      • 如果我从 Patient 类实例开始然后创建 XML,那将起作用。我需要它反过来。我有一个充满有问题的 XML 消息的数据库。我喜欢将它们转换为 java 类,如我的示例所示。
      • 愿意向我们展示在这种特殊情况下您对代码的了解吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-08
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多