bug 61630: further XSSFExportToXML performance improvements from Daniel (bug 61630 comment 15, attachment 35450)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1813332 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2017-10-25 18:19:12 +00:00
parent 02093f59dc
commit 2cf5a977aa

View File

@ -82,7 +82,7 @@ public class XSSFExportToXml implements Comparator<String>{
private static final POILogger LOG = POILogFactory.getLogger(XSSFExportToXml.class); private static final POILogger LOG = POILogFactory.getLogger(XSSFExportToXml.class);
private XSSFMap map; private XSSFMap map;
private final HashMap<String, Integer> indexMap = new HashMap<>();
/** /**
* Creates a new exporter and sets the mapping to be used when generating the XML output document * Creates a new exporter and sets the mapping to be used when generating the XML output document
* *
@ -146,8 +146,10 @@ public class XSSFExportToXml implements Comparator<String>{
tableMappings.put(commonXPath, table); tableMappings.put(commonXPath, table);
} }
indexMap.clear();
xpaths.sort(this); xpaths.sort(this);
indexMap.clear();
for(String xpath : xpaths) { for(String xpath : xpaths) {
XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath); XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath);
@ -401,6 +403,7 @@ public class XSSFExportToXml implements Comparator<String>{
String[] leftTokens = leftXpath.split("/"); String[] leftTokens = leftXpath.split("/");
String[] rightTokens = rightXpath.split("/"); String[] rightTokens = rightXpath.split("/");
String samePath = "";
int minLength = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length; int minLength = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length;
@ -412,47 +415,52 @@ public class XSSFExportToXml implements Comparator<String>{
String rightElementName = rightTokens[i]; String rightElementName = rightTokens[i];
if (leftElementName.equals(rightElementName)) { if (leftElementName.equals(rightElementName)) {
samePath += "/" + leftElementName;
localComplexTypeRootNode = getComplexTypeForElement(leftElementName, xmlSchema, localComplexTypeRootNode); localComplexTypeRootNode = getComplexTypeForElement(leftElementName, xmlSchema, localComplexTypeRootNode);
} else { } else {
int leftIndex = indexOfElementInComplexType(leftElementName,localComplexTypeRootNode); return indexOfElementInComplexType(samePath, leftElementName, rightElementName,localComplexTypeRootNode);
int rightIndex = indexOfElementInComplexType(rightElementName,localComplexTypeRootNode);
if (leftIndex!=-1 && rightIndex!=-1) {
if ( leftIndex < rightIndex) {
return -1;
}if ( leftIndex > rightIndex) {
return 1;
}
} /*else {
// NOTE: the xpath doesn't match correctly in the schema
}*/
} }
} }
return 0; return 0;
} }
private int indexOfElementInComplexType(String elementName,Node complexType) { private int indexOfElementInComplexType(String samePath,String leftElementName,String rightElementName,Node complexType) {
if(complexType == null) { if(complexType == null) {
return -1; return 0;
} }
int indexOf = -1;
int i = 0; int i = 0;
Node node = complexType.getFirstChild(); Node node = complexType.getFirstChild();
final String elementNameWithoutNamespace = removeNamespace(elementName); final String leftWithoutNamespace = removeNamespace(leftElementName);
int leftIndexOf = getAndStoreIndex(samePath, leftWithoutNamespace);
final String rightWithoutNamespace = removeNamespace(rightElementName);
int rightIndexOf = getAndStoreIndex(samePath, rightWithoutNamespace);
while (node != null) { while (node != null && (rightIndexOf==-1||leftIndexOf==-1)) {
if (node instanceof Element && "element".equals(node.getLocalName())) { if (node instanceof Element && "element".equals(node.getLocalName())) {
Node element = getNameOrRefElement(node); String elementValue = getNameOrRefElement(node).getNodeValue();
if (element.getNodeValue().equals(elementNameWithoutNamespace)) { if (elementValue.equals(leftWithoutNamespace)) {
indexOf = i; leftIndexOf = i;
break; indexMap.put(samePath+"/"+leftWithoutNamespace, leftIndexOf);
}
if (elementValue.equals(rightWithoutNamespace)) {
rightIndexOf = i;
indexMap.put(samePath+"/"+rightWithoutNamespace, leftIndexOf);
} }
} }
i++; i++;
node = node.getNextSibling(); node = node.getNextSibling();
} }
return indexOf; if(leftIndexOf == -1 || rightIndexOf == -1) {
return 0;
}
return Integer.compare(leftIndexOf, rightIndexOf);
}
private int getAndStoreIndex(String samePath,String withoutNamespace) {
String withPath = samePath+"/"+withoutNamespace;
return indexMap.getOrDefault(withPath, -1);
} }
private Node getNameOrRefElement(Node node) { private Node getNameOrRefElement(Node node) {