get xml as string instead of class with xstream

后端 未结 1 1781
情深已故
情深已故 2021-01-15 01:28

I have xml something like


  
   15
  

Instead of cr

相关标签:
1条回答
  • 2021-01-15 01:56

    The idia is to build up the xml of message by processing the HierarchicalStreamReader. If you go down into <messsage> by calling reader.goDown() unfortunately reader.getValue() does not return the whole content of this element.

    Model

        @XStreamAlias("parent")
        @XStreamConverter(value = ParentConverter.class)
        public class Parent {
            private final String message;
    
            public Parent(final String message) { this.message = message; }
            public String getMessage() { return message; }
        }
    

    Converter

        public class ParentConverter implements Converter {
            @Override
            public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) {
                return Parent.class.isAssignableFrom(type);
            }
    
            @Override
            public void marshal(Object source, HierarchicalStreamWriter writer,
                    MarshallingContext context) {
                throw new UnsupportedOperationException("unmarshaling only");
            }
    
            @Override
            public Object unmarshal(HierarchicalStreamReader reader,
                    UnmarshallingContext context) {
    
                reader.moveDown();
                if (!"message".equals(reader.getNodeName())) {
                    throw new ConversionException("Expected message, but was "
                            + reader.getNodeName());
                }
                final StringBuilder message = new StringBuilder();
                while (reader.hasMoreChildren()) {
                    reader.moveDown();
                    buildRecursiveMessage(reader, message);
                    reader.moveUp();
                }
                reader.moveUp();
    
                final Parent parent = new Parent(message.toString());
                return parent;
            }
    
            private void buildRecursiveMessage(final HierarchicalStreamReader reader,
                    final StringBuilder sb) {
                // Build start-tag
                final String nodeName = reader.getNodeName();
                sb.append("<" + nodeName);
    
                // Build attributes
                final int numAttributes = reader.getAttributeCount();
                if (numAttributes > 0) {
                    sb.append(" ");
                    for (int i = 0; i < numAttributes; i++) {
                        final String attributeName = reader.getAttributeName(i);
                        final String attributeValue = reader.getAttribute(i);
                        sb.append(attributeName + "=\"" + attributeValue + "\"");
    
                        final boolean lastAttribute = (i == numAttributes - 1);
                        if (!lastAttribute) {
                            sb.append(", ");
                        }
                    }
                }
    
                // Build children
                final boolean containsChildren = reader.hasMoreChildren();
                final boolean containsValue = !reader.getValue().isEmpty();
                final boolean empty = !containsChildren && !containsValue;
    
                sb.append(!empty ? ">" : " />");
    
                if (containsChildren) {
                    while (reader.hasMoreChildren()) {
                        reader.moveDown();
                        buildRecursiveMessage(reader, sb);
                        reader.moveUp();
                    }
                } else if (containsValue) {
                    sb.append(reader.getValue());
                }
    
                // Build end-tag
                if (!empty) {
                    sb.append("</" + nodeName + ">");
                }
            }
        }
    

    This test

        public static void main(String[] args) {
            final XStream xstream = new XStream();
            xstream.processAnnotations(Parent.class);
    
            // Deserialize
            final String xml = "<parent><message><type>15</type></message></parent>";
            final Parent parent = (Parent) xstream.fromXML(xml);
            System.out.println(parent.getMessage());
        }
    

    prints out

        <type>15</type>
    

    But it is not every the same content! It ignores for example whitespaces, <foo></foo> would mapped to <foo /> and I don't tested XML entities like &apos; etc.

    Maybe it's better to enclose your message in CDATA tags? Like

        <parent>
          <message>
           <![CDATA[
           <type>15</type>
           ]]>
          </message>
        </parent>
    
    0 讨论(0)
提交回复
热议问题