0
我试图建立一种可靠且快速的方式将XML转换为使用Java的JSON,并且我已经开始使用XStream来执行此任务。但是,当我在下面运行代码时由于空白(包括换行符)而导致测试失败,如果我删除这些字符,则测试会通过。在使用XStream将XML转换为JSON时忽略空白
@Test
public void testXmlWithWhitespaceBeforeStartElementCanBeConverted() throws Exception {
String xml =
"<root>\n" +
" <foo>bar</foo>\n" + // remove the newlines and white space to make the test pass
"</root>";
String expectedJson = "{\"root\": {\n" +
" \"foo\": bar\n" +
"}}";
String actualJSON = transformXmlToJson(xml);
Assert.assertEquals(expectedJson, actualJSON);
}
private String transformXmlToJson(String xml) throws XmlPullParserException {
XmlPullParser parser = XppFactory.createDefaultParser();
HierarchicalStreamReader reader = new XppReader(new StringReader(xml), parser, new NoNameCoder());
StringWriter write = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(write);
HierarchicalStreamCopier copier = new HierarchicalStreamCopier();
copier.copy(reader, jsonWriter);
jsonWriter.close();
return write.toString();
}
测试失败例外:
com.thoughtworks.xstream.io.json.AbstractJsonWriter$IllegalWriterStateException: Cannot turn from state SET_VALUE into state START_OBJECT for property foo
at com.thoughtworks.xstream.io.json.AbstractJsonWriter.handleCheckedStateTransition(AbstractJsonWriter.java:265)
at com.thoughtworks.xstream.io.json.AbstractJsonWriter.startNode(AbstractJsonWriter.java:227)
at com.thoughtworks.xstream.io.json.AbstractJsonWriter.startNode(AbstractJsonWriter.java:232)
at com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier.copy(HierarchicalStreamCopier.java:36)
at com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier.copy(HierarchicalStreamCopier.java:47)
at testConvertXmlToJSON.transformXmlToJson(testConvertXmlToJSON.java:30)
有没有办法来告诉复制过程中忽略忽略的空白。我找不到任何明显的方法来实现这一行为,但我认为它应该在那里。我知道我可以预先处理XML以删除空白区域,或者也许只是使用另一个库。
更新 我可以解决此问题使用HierarchicalStreamReader接口的装饰以及手工压制的空白点,这仍然不觉得理想虽然。这看起来像下面的代码,这将使测试通过。
public class IgnoreWhitespaceHierarchicalStreamReader implements HierarchicalStreamReader {
private HierarchicalStreamReader innerHierarchicalStreamReader;
public IgnoreWhitespaceHierarchicalStreamReader(HierarchicalStreamReader hierarchicalStreamReader) {
this.innerHierarchicalStreamReader = hierarchicalStreamReader;
}
public String getValue() {
String getValue = innerHierarchicalStreamReader.getValue();
System.out.printf("getValue = '%s'\n", getValue);
if(innerHierarchicalStreamReader.hasMoreChildren() && getValue.length() >0) {
if(getValue.matches("^\\s+$")) {
System.out.printf("*** White space value suppressed\n");
getValue = "";
}
}
return getValue;
}
// rest of interface ...
任何帮助表示赞赏。
感谢您的答复,但我没有看到我的表演XML的比较。你是指在删除空白处的decarator内吗? – Darren 2013-03-28 10:28:30
我的意思是当你调用Assert.assertEquals时。这两个参数都是String对象,因此将调用String.equals()方法。相反,您将不得不创建XMLObject类来重写它的equals方法来执行XML比较。 – ABose 2013-04-03 08:06:59
assertEquals正在测试JSON字符串而不是XML字符串。我同意,如果JSON字符串的内容可能不准确,因此测试可能因此失败(但我没有那么远),我应该测试等价性。测试只是为了简洁而显示,并不是引发异常的原因。 – Darren 2013-04-04 05:18:31