converter.xml.rowtocol.SaxXMLRowToColRebuilder Maven / Gradle / Ivy
package converter.xml.rowtocol;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/*
* xml重建器。用于实现xml某节点的行列转换
* @author liuqiangm
*/
public class SaxXMLRowToColRebuilder extends DefaultHandler {
private static boolean rebuild = false;
private XMLTreeNode root;
private String value;
private Set discardNodeStrSet = new TreeSet<>();
private Map> tagSubNodeMap = new TreeMap<>();
private LinkedList treeNodes = new LinkedList<>();
public String rebuildPath;
public SaxXMLRowToColRebuilder(String rebuildPath) {
this.rebuildPath = rebuildPath;
}
public SaxXMLRowToColRebuilder(String rebuildPath, Set discardNodeStrSet) {
this.rebuildPath = rebuildPath;
this.discardNodeStrSet = discardNodeStrSet;
}
public SaxXMLRowToColRebuilder(String rebuildPath, Set discardNodeStrSet,
Map> tagSubNodeMap) {
this.rebuildPath = rebuildPath;
this.discardNodeStrSet.addAll(discardNodeStrSet);
this.tagSubNodeMap.putAll(tagSubNodeMap);
}
public SaxXMLRowToColRebuilder(String rebuildPath, Map> tagSubNodeMap) {
this.rebuildPath = rebuildPath;
this.tagSubNodeMap = tagSubNodeMap;
}
public SaxXMLRowToColRebuilder(String rebuildPath, InputStream inputStream) {
this.rebuildPath = rebuildPath;
if (inputStream != null) {
try {
tagSubNodeMapAdd(JSON.parseObject(inputStream, JSONObject.class));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public SaxXMLRowToColRebuilder(String rebuildPath, String jsonStr) {
this.rebuildPath = rebuildPath;
tagSubNodeMapAdd(JSON.parseObject(jsonStr));
}
private void tagSubNodeMapAdd(JSONObject jsonObject) {
for (String key : jsonObject.keySet()) {
Map keyMap = new HashMap<>();
tagSubNodeMap.put(key, keyMap);
JSONObject keyObject = jsonObject.getJSONObject(key);
for (String key1 : keyObject.keySet()) {
keyMap.put(key1, keyObject.getString(key1));
}
}
}
/*
* 解析xml元素
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
treeNodes.push(new XMLTreeNode(qName));
super.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
XMLTreeNode currNode = treeNodes.pop();
if (treeNodes.size() == 0) {
root = currNode;
} else {
treeNodes.peek().addSunNode(currNode);
}
currNode.setValue(value);
value = null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
value = new String(ch, start, length).trim();
}
public String getRebuildedStr() {
if (!rebuild) {
treeRebuild(root, "");
}
return XMLOutputUtils.createXMLString(root);
}
public void writeToOutputStream(OutputStream outputStream) {
if (!rebuild) {
treeRebuild(root, "");
}
XMLOutputUtils.writeXMLToOutputStream(root, outputStream);
}
public void treeRebuild(XMLTreeNode treeNode, String path) {
if (path == null || "".equals(path)) {
path = treeNode.getKey();
} else {
path += "." + treeNode.getKey();
}
if (rebuildPath.startsWith(path) && !rebuildPath.equals(path)) {
for (XMLTreeNode subXMLTreeNode : treeNode.getSunNodeList()) {
treeRebuild(subXMLTreeNode, path);
}
} else if (rebuildPath.equals(path)) {
reviseXMLTreeNode(treeNode);
}
}
public void reviseXMLTreeNode(XMLTreeNode treeNode) {
LinkedList treeNodeLayer = new LinkedList<>(treeNode.getSunNodeList());
treeNode.getSunNodeList().clear();
while (true) {
if (treeNodeLayer.size() != 0 && treeNodeLayer.peekFirst().sunNodeList.size() != 0) {
XMLTreeNode subNode = new XMLTreeNode();
boolean flag = false;
int subIndex = 1;
for (XMLTreeNode node : treeNodeLayer) {
XMLTreeNode tmpSubNode = node.sunNodeList.pollFirst();
subNode.setKey(tmpSubNode.getKey());
tmpSubNode.setKey(node.getKey() + "_" + subIndex);
subIndex++;
if (discardNodeStrSet.contains(tmpSubNode.getKey())) {
flag = true;
}
subNode.sunNodeList.add(tmpSubNode);
}
if (!flag) {
Map subTagNodeMap = tagSubNodeMap.getOrDefault(subNode.getKey(),
Collections.emptyMap());
for (Map.Entry subTagNode : subTagNodeMap.entrySet()) {
XMLTreeNode subTagXMLTreeNode = new XMLTreeNode(subTagNode.getKey());
subTagXMLTreeNode.setValue(subTagNode.getValue());
subNode.sunNodeList.addFirst(subTagXMLTreeNode);
}
treeNode.addSunNode(subNode);
}
} else {
break;
}
}
}
}