我有以下XML:
<docs>
<doc>
<person>
<name>John Doe</name>
<description>
<age>23</age>
<alias>M C</alias>
</description>
<description>
<age>24</age>
<alias>John</alias>
</description>
</person>
<doc>
<doc>
<person>
<name>John Doe</name>
<description>
<age>24</age>
<alias>Steve</alias>
</description>
</person>
<doc>
</docs>
我无法控制xml。我得到的只是这样的xml文档和元素的xpath。我编写了一个java程序来读取数据并将其转换为Json对象。我正在使用xPath和dom解析器,因为我们得到xPath for xml,我想我会利用它,因为xPath将来可能会改变。所以我对属性文件中的所有元素都有xPath,所以如果有更改,我将在程序中进行最小的更改。不幸的是程序应该不区分大小写,因此我使用translate(xPath)来处理它。我有以下课程
public class Person {
private List<String> name;
private List<String> age;
private List<String> alias;
//getter and setter
}
问题是拥有多个doc节点,每个节点都可以有多个age和alias元素。之前它不是必需的,所以我使用XPath来获取文本,但现在我不能使用它,因为// person / description的xPath将返回3个节点,2个来自第一个doc,另一个来自另一个doc。问题是我需要区分描述标签,以确定它是来自第一个文档还是来自另一个文档。所以最终的Json看起来像
{
"docs":
{
"doc":
[
{
"description":
[
{
"age": 23,
"alias": "M C"
},
{
"age": 24,
"alias": "John"
}
]
},
{
"description":
[
{
"age": 24,
"alias": "Steve"
}
]
}
]
}
}
所以我能想到的是编译xPath表达式 - // docs / doc,此时我将有2个节点并获取子节点并通过获取子节点进行循环并执行类似if
element.getTagName().equalsIgnoreCase("age")
然后添加到年龄列表,然后像列表一样,所以我最终会有
docs[[[23, "M C"],[24, "John"]],[[24, "Steve"]]]
有更好的想法吗?
答案 0 :(得分:0)
XPath的替代方案是Java JSON library。该库具有使用XML和生成JSON的功能。要完成此转换,请使用以下命令:
public class Main {
private static int SPACES_PER_INDENT = 4;
public static void main(String[] args) throws Exception {
try {
// Citation: https://stackoverflow.com/questions/1823264/quickest-way-to-convert-xml-to-json-in-java
URI file = Main.class.getClassLoader().getResource("docs.xml").toURI();
String xmlContents = readFromInputStream(file);
JSONObject jsonContents = XML.toJSONObject(xmlContents);
String jsonString = jsonContents.toString(SPACES_PER_INDENT);
System.out.println(jsonString);
}
catch (JSONException e) {
e.printStackTrace();
}
}
private static String readFromInputStream(URI uri) throws IOException {
// Citation: http://www.baeldung.com/reading-file-in-java
Path path = Paths.get(uri);
StringBuilder data = new StringBuilder();
Stream<String> lines = Files.lines(path);
lines.forEach(line -> data.append(line).append("\n"));
lines.close();
return data.toString();
}
}
类路径中存在的docs.xml
内容如下(请注意,我将问题中的<doc>...<doc>
标记更改为<doc>...</doc>
):
<docs>
<doc>
<person>
<name>John Doe</name>
<description>
<age>23</age>
<alias>M C</alias>
</description>
<description>
<age>24</age>
<alias>John</alias>
</description>
</person>
</doc>
<doc>
<person>
<name>John Doe</name>
<description>
<age>24</age>
<alias>Steve</alias>
</description>
</person>
</doc>
</docs>
这个项目的pom.xml
是:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow.albanoj2</groupId>
<artifactId>XmlToJson</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
</dependencies>
</project>
结果输出为:
{"docs": {"doc": [
{"person": {
"name": "John Doe",
"description": [
{
"alias": "M C",
"age": 23
},
{
"alias": "John",
"age": 24
}
]
}},
{"person": {
"name": "John Doe",
"description": {
"alias": "Steve",
"age": 24
}
}}
]}}
如果更容易阅读,此解决方案的源代码包含在以下存储库中:https://github.com/albanoj2/XmlToJsonDocTranslation。请注意,此答案的大部分内容源自Quickest way to convert XML to JSON in Java,但已根据此问题的特定需求进行了定制(例如从文件中读取XML)。