XStream: 如何忽略空格

XStream: How to ignore spaces

是否可以通过 XStream 解析来忽略空格:

public class TestTest {

    @Test
    public void smokeTest() {
        InputStream file = TestTest.class.getResourceAsStream("TestTest.xml");
        XStream xStream = new XStream();
        xStream.ignoreUnknownElements();
        xStream.processAnnotations(Mother.class);

        Mother mother = (Mother) xStream.fromXML(file);
    }

    @XStreamAlias("mother")
    public class Mother {

        @XStreamAsAttribute
        public String name;

        public int age;
    }
}

XML:

<?xml version="1.0" encoding="UTF-8"?>
<mother name="Jenny">
        <age> 33 </age>
</mother>

错误:

com.thoughtworks.xstream.converters.ConversionException: For input string: " 33 " : For input string: " 33 "
---- Debugging information ----
message             : For input string: " 33 "
cause-exception     : java.lang.NumberFormatException
cause-message       : For input string: " 33 "
class               : java.lang.Integer
required-type       : java.lang.Integer
converter-type      : com.thoughtworks.xstream.converters.SingleValueConverterWrapper
wrapped-converter   : com.thoughtworks.xstream.converters.basic.IntConverter
path                : /mother/age
line number         : 3
class[1]            : de.mosst.xstream.test.TestTest$Mother
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version             : 1.4.7
-------------------------------
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:474)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:406)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1185)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1169)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1049)
    at de.mosst.xstream.test.TestTest.smokeTest(TestTest.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NumberFormatException: For input string: " 33 "
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Long.parseLong(Long.java:578)
    at java.lang.Long.valueOf(Long.java:776)
    at java.lang.Long.decode(Long.java:928)
    at com.thoughtworks.xstream.converters.basic.IntConverter.fromString(IntConverter.java:27)
    at com.thoughtworks.xstream.converters.SingleValueConverterWrapper.fromString(SingleValueConverterWrapper.java:41)
    at com.thoughtworks.xstream.converters.SingleValueConverterWrapper.unmarshal(SingleValueConverterWrapper.java:49)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    ... 38 more

我没有找到 trim 字符串值的选项。

您可以添加自定义转换器,它将 trim 空格:

   xStream.registerConverter(new IntConverter() {
        @Override
        public Object fromString(String str) {
            return super.fromString(str.trim());
        }

    });

或者,您可以添加一个包装器来预处理所有 SingleValueConverter 的输入:

    XStream xStream = new XStream() {
        @Override
        public void registerConverter(SingleValueConverter converter, int priority) {
            SingleValueConverter stringPreprocessor = new SingleValueConverterWrapper(converter) {

                @Override
                public Object fromString(String str) {
                    // You can trim whitespace or do other preprocessing here
                    return converter.fromString(str.trim());
                }

            };
            super.registerConverter(stringPreprocessor, priority);
        }
    };