我需要将docx文件格式(即openXML格式)转换成JSON格式。我需要一些指导来完成此操作。提前致谢。
您可以查看Json-lib Java库,该库提供了XML到JSON的转换功能。
String xml = "<hello><test>1.2</test><test2>123</test2></hello>";
XMLSerializer xmlSerializer = new XMLSerializer();
JSON json = xmlSerializer.read( xml );
如果你需要根标签,只需添加一个外层虚拟标签:
String xml = "<hello><test>1.2</test><test2>123</test2></hello>";
XMLSerializer xmlSerializer = new XMLSerializer();
JSON json = xmlSerializer.read("<x>" + xml + "</x>");
{"test":"1.2","test2":"123"}
而不是 {"hello":{"test":"1.2","test2":"123"}}
,也就是说它只打印叶子节点(<hello>
标签丢失了)。如果我们添加一个中间节点(作为<hello>
的子节点和<test>
的父节点),同样会被忽略。这是一个配置问题吗? - bluishXML和JSON之间没有直接的映射关系;XML携带类型信息(每个元素都有名称)以及命名空间。因此,除非每个JSON对象都嵌入了类型信息,否则转换将会有损失。
但这并不一定重要。重要的是JSON的使用者知道数据契约。例如,给定以下XML:
<books>
<book author="Jimbo Jones" title="Bar Baz">
<summary>Foo</summary>
</book>
<book title="Don't Care" author="Fake Person">
<summary>Dummy Data</summary>
</book>
</books>
{
"books": [
{ "author": "Jimbo Jones", "title": "Bar Baz", "summary": "Foo" },
{ "author": "Fake Person", "title": "Don't Care", "summary": "Dummy Data" },
]
}
books
集合中的每个对象都是一个 book
对象。DataContractJsonSerializer
将类序列化为 JSON。如果您对各种实现不满意,可以尝试自己编写。这是我今天下午编写的一些代码,可帮助您入门。它与net.sf.json和apache common-lang兼容:
static public JSONObject readToJSON(InputStream stream) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
SAXJsonParser handler = new SAXJsonParser();
parser.parse(stream, handler);
return handler.getJson();
}
以下是SAXJsonParser的实现:
package xml2json;
import net.sf.json.*;
import org.apache.commons.lang.StringUtils;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
public class SAXJsonParser extends DefaultHandler {
static final String TEXTKEY = "_text";
JSONObject result;
List<JSONObject> stack;
public SAXJsonParser(){}
public JSONObject getJson(){return result;}
public String attributeName(String name){return "@"+name;}
public void startDocument () throws SAXException {
stack = new ArrayList<JSONObject>();
stack.add(0,new JSONObject());
}
public void endDocument () throws SAXException {result = stack.remove(0);}
public void startElement (String uri, String localName,String qName, Attributes attributes) throws SAXException {
JSONObject work = new JSONObject();
for (int ix=0;ix<attributes.getLength();ix++)
work.put( attributeName( attributes.getLocalName(ix) ), attributes.getValue(ix) );
stack.add(0,work);
}
public void endElement (String uri, String localName, String qName) throws SAXException {
JSONObject pop = stack.remove(0); // examine stack
Object stashable = pop;
if (pop.containsKey(TEXTKEY)) {
String value = pop.getString(TEXTKEY).trim();
if (pop.keySet().size()==1) stashable = value; // single value
else if (StringUtils.isBlank(value)) pop.remove(TEXTKEY);
}
JSONObject parent = stack.get(0);
if (!parent.containsKey(localName)) { // add new object
parent.put( localName, stashable );
}
else { // aggregate into arrays
Object work = parent.get(localName);
if (work instanceof JSONArray) {
((JSONArray)work).add(stashable);
}
else {
parent.put(localName,new JSONArray());
parent.getJSONArray(localName).add(work);
parent.getJSONArray(localName).add(stashable);
}
}
}
public void characters (char ch[], int start, int length) throws SAXException {
JSONObject work = stack.get(0); // aggregate characters
String value = (work.containsKey(TEXTKEY) ? work.getString(TEXTKEY) : "" );
work.put(TEXTKEY, value+new String(ch,start,length) );
}
public void warning (SAXParseException e) throws SAXException {
System.out.println("warning e=" + e.getMessage());
}
public void error (SAXParseException e) throws SAXException {
System.err.println("error e=" + e.getMessage());
}
public void fatalError (SAXParseException e) throws SAXException {
System.err.println("fatalError e=" + e.getMessage());
throw e;
}
}
org.json命名空间中的XML类提供了这个功能。
您需要调用静态的toJSONObject方法
将格式良好(但不一定有效)的XML字符串转换为JSONObject。在此转换中可能会丢失某些信息,因为JSON是数据格式,而XML是文档格式。XML使用元素、属性和内容文本,而JSON使用无序的名称/值对集合和值数组。JSON不喜欢区分元素和属性。类似元素的序列表示为JSONArray。内容文本可以放置在“content”成员中。注释、prologs、DTD和<[[ ]]>被忽略。
<person>
<firstname>Joe</firstname>
<lastname>Walnes</lastname>
<phone>
<code>123</code>
<number>1234-456</number>
</phone>
<fax>
<code>123</code>
<number>9999-999</number>
</fax>
</person>
public class Person {
private String firstname;
private String lastname;
private PhoneNumber phone;
private PhoneNumber fax;
// ... constructors and methods
}
String xml = "<person>...</person>";
XStream xstream = new XStream();
Person person = (Person)xstream.fromXML(xml);
XStream xstream = new XStream(new JettisonMappedXmlDriver());
String json = xstream.toXML(person);
toXML()
,但由于使用了Jettison驱动程序,XStream将生成JSON。我以前用过docx4j,值得一看。
你也可以看看我开源的unXml库,它可以在Maven Central上获得。
它很轻量级,并且有一个简单的语法来从你的xml中挑选出XPaths,并将它们作为Json属性返回到Jackson ObjectNode
中。
使用
xmlSerializer.setForceTopLevelObject(true)
在生成的 JSON 中包含根元素。
你的代码应该像这样:
String xml = "<hello><test>1.2</test><test2>123</test2></hello>";
XMLSerializer xmlSerializer = new XMLSerializer();
xmlSerializer.setForceTopLevelObject(true);
JSON json = xmlSerializer.read(xml);