get xml as string instead of class with xstream

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

I have xml something like


  
   15
  

Instead of cr

1条回答
  •  萌比男神i
    2021-01-15 01:56

    The idia is to build up the xml of message by processing the HierarchicalStreamReader. If you go down into 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("");
                }
            }
        }
    

    This test

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

    prints out

        15
    

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

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

        
          
           15
           ]]>
          
        
    

    0 讨论(0)
提交回复
热议问题