Bug 56169: Fix NPE during export to XML with xs:all
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1577907 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f597633624
commit
7c3f1a926b
@ -261,7 +261,6 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||||||
* @return true, if document is valid
|
* @return true, if document is valid
|
||||||
*/
|
*/
|
||||||
private boolean isValid(Document xml) throws SAXException{
|
private boolean isValid(Document xml) throws SAXException{
|
||||||
boolean isValid = false;
|
|
||||||
try{
|
try{
|
||||||
String language = "http://www.w3.org/2001/XMLSchema";
|
String language = "http://www.w3.org/2001/XMLSchema";
|
||||||
SchemaFactory factory = SchemaFactory.newInstance(language);
|
SchemaFactory factory = SchemaFactory.newInstance(language);
|
||||||
@ -270,14 +269,14 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||||||
Schema schema = factory.newSchema(source);
|
Schema schema = factory.newSchema(source);
|
||||||
Validator validator = schema.newValidator();
|
Validator validator = schema.newValidator();
|
||||||
validator.validate(new DOMSource(xml));
|
validator.validate(new DOMSource(xml));
|
||||||
|
|
||||||
//if no exceptions where raised, the document is valid
|
//if no exceptions where raised, the document is valid
|
||||||
isValid=true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return isValid;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -517,7 +516,7 @@ public class XSSFExportToXml implements Comparator<String>{
|
|||||||
Node sequence = complexTypeChildList.item(j);
|
Node sequence = complexTypeChildList.item(j);
|
||||||
|
|
||||||
if ( sequence instanceof Element) {
|
if ( sequence instanceof Element) {
|
||||||
if (sequence.getLocalName().equals("sequence")) {
|
if (sequence.getLocalName().equals("sequence") || sequence.getLocalName().equals("all")) {
|
||||||
complexTypeNode = sequence;
|
complexTypeNode = sequence;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,536 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.xssf.extractor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.OutputKeys;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
import javax.xml.validation.SchemaFactory;
|
||||||
|
import javax.xml.validation.Validator;
|
||||||
|
|
||||||
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFTable;
|
||||||
|
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
|
||||||
|
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
|
||||||
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STXmlDataType;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NamedNodeMap;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Maps an XLSX to an XML according to one of the mapping defined.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The output XML Schema must respect this limitations:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li> all mandatory elements and attributes must be mapped (enable validation to check this)</li>
|
||||||
|
*
|
||||||
|
* <li> no <any> in complex type/element declaration </li>
|
||||||
|
* <li> no <anyAttribute> attributes declaration </li>
|
||||||
|
* <li> no recursive structures: recursive structures can't be nested more than one level </li>
|
||||||
|
* <li> no abstract elements: abstract complex types can be declared but must not be used in elements. </li>
|
||||||
|
* <li> no mixed content: an element can't contain simple text and child element(s) together </li>
|
||||||
|
* <li> no <substitutionGroup> in complex type/element declaration </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class XSSFExportToXml implements Comparator<String>{
|
||||||
|
|
||||||
|
private XSSFMap map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new exporter and sets the mapping to be used when generating the XML output document
|
||||||
|
*
|
||||||
|
* @param map the mapping rule to be used
|
||||||
|
*/
|
||||||
|
public XSSFExportToXml(XSSFMap map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Exports the data in an XML stream
|
||||||
|
*
|
||||||
|
* @param os OutputStream in which will contain the output XML
|
||||||
|
* @param validate if true, validates the XML againts the XML Schema
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws TransformerException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
*/
|
||||||
|
public void exportToXML(OutputStream os, boolean validate) throws SAXException, ParserConfigurationException, TransformerException {
|
||||||
|
exportToXML(os, "UTF-8", validate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Document getEmptyDocument() throws ParserConfigurationException{
|
||||||
|
|
||||||
|
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
||||||
|
Document doc = docBuilder.newDocument();
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports the data in an XML stream
|
||||||
|
*
|
||||||
|
* @param os OutputStream in which will contain the output XML
|
||||||
|
* @param encoding the output charset encoding
|
||||||
|
* @param validate if true, validates the XML againts the XML Schema
|
||||||
|
* @throws SAXException
|
||||||
|
* @throws ParserConfigurationException
|
||||||
|
* @throws TransformerException
|
||||||
|
* @throws InvalidFormatException
|
||||||
|
*/
|
||||||
|
public void exportToXML(OutputStream os, String encoding, boolean validate) throws SAXException, ParserConfigurationException, TransformerException{
|
||||||
|
List<XSSFSingleXmlCell> singleXMLCells = map.getRelatedSingleXMLCell();
|
||||||
|
List<XSSFTable> tables = map.getRelatedTables();
|
||||||
|
|
||||||
|
String rootElement = map.getCtMap().getRootElement();
|
||||||
|
|
||||||
|
Document doc = getEmptyDocument();
|
||||||
|
|
||||||
|
Element root = null;
|
||||||
|
|
||||||
|
if (isNamespaceDeclared()) {
|
||||||
|
root=doc.createElementNS(getNamespace(),rootElement);
|
||||||
|
} else {
|
||||||
|
root = doc.createElementNS("", rootElement);
|
||||||
|
}
|
||||||
|
doc.appendChild(root);
|
||||||
|
|
||||||
|
|
||||||
|
List<String> xpaths = new Vector<String>();
|
||||||
|
Map<String,XSSFSingleXmlCell> singleXmlCellsMappings = new HashMap<String,XSSFSingleXmlCell>();
|
||||||
|
Map<String,XSSFTable> tableMappings = new HashMap<String,XSSFTable>();
|
||||||
|
|
||||||
|
for(XSSFSingleXmlCell simpleXmlCell : singleXMLCells) {
|
||||||
|
xpaths.add(simpleXmlCell.getXpath());
|
||||||
|
singleXmlCellsMappings.put(simpleXmlCell.getXpath(), simpleXmlCell);
|
||||||
|
}
|
||||||
|
for(XSSFTable table : tables) {
|
||||||
|
String commonXPath = table.getCommonXpath();
|
||||||
|
xpaths.add(commonXPath);
|
||||||
|
tableMappings.put(commonXPath, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Collections.sort(xpaths,this);
|
||||||
|
|
||||||
|
for(String xpath : xpaths) {
|
||||||
|
|
||||||
|
XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath);
|
||||||
|
XSSFTable table = tableMappings.get(xpath);
|
||||||
|
|
||||||
|
if (!xpath.matches(".*\\[.*")) {
|
||||||
|
|
||||||
|
// Exports elements and attributes mapped with simpleXmlCell
|
||||||
|
if (simpleXmlCell!=null) {
|
||||||
|
XSSFCell cell = simpleXmlCell.getReferencedCell();
|
||||||
|
if (cell!=null) {
|
||||||
|
Node currentNode = getNodeByXPath(xpath,doc.getFirstChild(),doc,false);
|
||||||
|
STXmlDataType.Enum dataType = simpleXmlCell.getXmlDataType();
|
||||||
|
mapCellOnNode(cell,currentNode,dataType);
|
||||||
|
|
||||||
|
//remove nodes which are empty in order to keep the output xml valid
|
||||||
|
if("".equals(currentNode.getTextContent()) && currentNode.getParentNode() != null) {
|
||||||
|
currentNode.getParentNode().removeChild(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exports elements and attributes mapped with tables
|
||||||
|
if (table!=null) {
|
||||||
|
|
||||||
|
List<XSSFXmlColumnPr> tableColumns = table.getXmlColumnPrs();
|
||||||
|
|
||||||
|
XSSFSheet sheet = table.getXSSFSheet();
|
||||||
|
|
||||||
|
int startRow = table.getStartCellReference().getRow();
|
||||||
|
// In mappings created with Microsoft Excel the first row contains the table header and must be skipped
|
||||||
|
startRow +=1;
|
||||||
|
|
||||||
|
int endRow = table.getEndCellReference().getRow();
|
||||||
|
|
||||||
|
for(int i = startRow; i<= endRow; i++) {
|
||||||
|
XSSFRow row = sheet.getRow(i);
|
||||||
|
|
||||||
|
Node tableRootNode = getNodeByXPath(table.getCommonXpath(),doc.getFirstChild(),doc,true);
|
||||||
|
|
||||||
|
short startColumnIndex = table.getStartCellReference().getCol();
|
||||||
|
for(int j = startColumnIndex; j<= table.getEndCellReference().getCol();j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell!=null) {
|
||||||
|
XSSFXmlColumnPr pointer = tableColumns.get(j-startColumnIndex);
|
||||||
|
String localXPath = pointer.getLocalXPath();
|
||||||
|
Node currentNode = getNodeByXPath(localXPath,tableRootNode,doc,false);
|
||||||
|
STXmlDataType.Enum dataType = pointer.getXmlDataType();
|
||||||
|
|
||||||
|
|
||||||
|
mapCellOnNode(cell,currentNode,dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: implement filtering management in xpath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isValid = true;
|
||||||
|
if (validate) {
|
||||||
|
isValid =isValid(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
//Output the XML
|
||||||
|
|
||||||
|
//set up a transformer
|
||||||
|
TransformerFactory transfac = TransformerFactory.newInstance();
|
||||||
|
Transformer trans = transfac.newTransformer();
|
||||||
|
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
|
trans.setOutputProperty(OutputKeys.ENCODING, encoding);
|
||||||
|
|
||||||
|
//create string from xml tree
|
||||||
|
|
||||||
|
StreamResult result = new StreamResult(os);
|
||||||
|
DOMSource source = new DOMSource(doc);
|
||||||
|
trans.transform(source, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the generated XML against the XML Schema associated with the XSSFMap
|
||||||
|
*
|
||||||
|
* @param xml the XML to validate
|
||||||
|
* @return true, if document is valid
|
||||||
|
*/
|
||||||
|
private boolean isValid(Document xml) throws SAXException{
|
||||||
|
boolean isValid = false;
|
||||||
|
try{
|
||||||
|
String language = "http://www.w3.org/2001/XMLSchema";
|
||||||
|
SchemaFactory factory = SchemaFactory.newInstance(language);
|
||||||
|
|
||||||
|
Source source = new DOMSource(map.getSchema());
|
||||||
|
Schema schema = factory.newSchema(source);
|
||||||
|
Validator validator = schema.newValidator();
|
||||||
|
validator.validate(new DOMSource(xml));
|
||||||
|
//if no exceptions where raised, the document is valid
|
||||||
|
isValid=true;
|
||||||
|
|
||||||
|
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void mapCellOnNode(XSSFCell cell, Node node, STXmlDataType.Enum outputDataType) {
|
||||||
|
|
||||||
|
String value ="";
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
|
||||||
|
case XSSFCell.CELL_TYPE_STRING: value = cell.getStringCellValue(); break;
|
||||||
|
case XSSFCell.CELL_TYPE_BOOLEAN: value += cell.getBooleanCellValue(); break;
|
||||||
|
case XSSFCell.CELL_TYPE_ERROR: value = cell.getErrorCellString(); break;
|
||||||
|
case XSSFCell.CELL_TYPE_FORMULA:
|
||||||
|
if (cell.getCachedFormulaResultType() == Cell.CELL_TYPE_STRING) {
|
||||||
|
value = cell.getStringCellValue();
|
||||||
|
} else {
|
||||||
|
value += cell.getNumericCellValue();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XSSFCell.CELL_TYPE_NUMERIC:
|
||||||
|
if (DateUtil.isCellDateFormatted(cell)) {
|
||||||
|
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
value += sdf.format(cell.getDateCellValue());
|
||||||
|
} else {
|
||||||
|
value += cell.getRawValue();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (node instanceof Element) {
|
||||||
|
Element currentElement = (Element) node;
|
||||||
|
currentElement.setTextContent(value);
|
||||||
|
} else {
|
||||||
|
node.setNodeValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeNamespace(String elementName) {
|
||||||
|
return elementName.matches(".*:.*")?elementName.split(":")[1]:elementName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private Node getNodeByXPath(String xpath,Node rootNode,Document doc,boolean createMultipleInstances) {
|
||||||
|
String[] xpathTokens = xpath.split("/");
|
||||||
|
|
||||||
|
|
||||||
|
Node currentNode =rootNode;
|
||||||
|
// The first token is empty, the second is the root node
|
||||||
|
for(int i =2; i<xpathTokens.length;i++) {
|
||||||
|
|
||||||
|
String axisName = removeNamespace(xpathTokens[i]);
|
||||||
|
|
||||||
|
|
||||||
|
if (!axisName.startsWith("@")) {
|
||||||
|
|
||||||
|
NodeList list =currentNode.getChildNodes();
|
||||||
|
|
||||||
|
Node selectedNode = null;
|
||||||
|
if (!(createMultipleInstances && i==xpathTokens.length-1) ) {
|
||||||
|
// select the last child node only if we need to map to a single cell
|
||||||
|
selectedNode = selectNode(axisName, list);
|
||||||
|
}
|
||||||
|
if (selectedNode==null) {
|
||||||
|
selectedNode = createElement(doc, currentNode, axisName);
|
||||||
|
}
|
||||||
|
currentNode = selectedNode;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
Node attribute = createAttribute(doc, currentNode, axisName);
|
||||||
|
|
||||||
|
currentNode = attribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node createAttribute(Document doc, Node currentNode, String axisName) {
|
||||||
|
String attributeName = axisName.substring(1);
|
||||||
|
NamedNodeMap attributesMap = currentNode.getAttributes();
|
||||||
|
Node attribute = attributesMap.getNamedItem(attributeName);
|
||||||
|
if (attribute==null) {
|
||||||
|
attribute = doc.createAttributeNS("", attributeName);
|
||||||
|
attributesMap.setNamedItem(attribute);
|
||||||
|
}
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node createElement(Document doc, Node currentNode, String axisName) {
|
||||||
|
Node selectedNode;
|
||||||
|
if (isNamespaceDeclared()) {
|
||||||
|
selectedNode =doc.createElementNS(getNamespace(),axisName);
|
||||||
|
} else {
|
||||||
|
selectedNode = doc.createElementNS("", axisName);
|
||||||
|
}
|
||||||
|
currentNode.appendChild(selectedNode);
|
||||||
|
return selectedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node selectNode(String axisName, NodeList list) {
|
||||||
|
Node selectedNode = null;
|
||||||
|
for(int j=0;j<list.getLength();j++) {
|
||||||
|
Node node = list.item(j);
|
||||||
|
if (node.getNodeName().equals(axisName)) {
|
||||||
|
selectedNode=node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isNamespaceDeclared() {
|
||||||
|
String schemaNamespace = getNamespace();
|
||||||
|
return schemaNamespace!=null && !schemaNamespace.equals("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNamespace() {
|
||||||
|
return map.getCTSchema().getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two xpaths to define an ordering according to the XML Schema
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compare(String leftXpath, String rightXpath) {
|
||||||
|
Node xmlSchema = map.getSchema();
|
||||||
|
|
||||||
|
String[] leftTokens = leftXpath.split("/");
|
||||||
|
String[] rightTokens = rightXpath.split("/");
|
||||||
|
|
||||||
|
int minLenght = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length;
|
||||||
|
|
||||||
|
Node localComplexTypeRootNode = xmlSchema;
|
||||||
|
|
||||||
|
for(int i =1;i <minLenght; i++) {
|
||||||
|
|
||||||
|
String leftElementName =leftTokens[i];
|
||||||
|
String rightElementName = rightTokens[i];
|
||||||
|
|
||||||
|
if (leftElementName.equals(rightElementName)) {
|
||||||
|
Node complexType = getComplexTypeForElement(leftElementName, xmlSchema,localComplexTypeRootNode);
|
||||||
|
localComplexTypeRootNode = complexType;
|
||||||
|
} else {
|
||||||
|
int leftIndex = indexOfElementInComplexType(leftElementName,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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int indexOfElementInComplexType(String elementName,Node complexType) {
|
||||||
|
|
||||||
|
NodeList list = complexType.getChildNodes();
|
||||||
|
int indexOf = -1;
|
||||||
|
|
||||||
|
for(int i=0; i< list.getLength();i++) {
|
||||||
|
Node node = list.item(i);
|
||||||
|
if (node instanceof Element) {
|
||||||
|
if (node.getLocalName().equals("element")) {
|
||||||
|
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||||
|
if (nameAttribute.getNodeValue().equals(removeNamespace(elementName))) {
|
||||||
|
indexOf = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indexOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getComplexTypeForElement(String elementName,Node xmlSchema,Node localComplexTypeRootNode) {
|
||||||
|
String elementNameWithoutNamespace = removeNamespace(elementName);
|
||||||
|
|
||||||
|
String complexTypeName = getComplexTypeNameFromChildren(localComplexTypeRootNode, elementNameWithoutNamespace);
|
||||||
|
|
||||||
|
// Note: we expect that all the complex types are defined at root level
|
||||||
|
Node complexTypeNode = null;
|
||||||
|
if (!"".equals(complexTypeName)) {
|
||||||
|
complexTypeNode = getComplexTypeNodeFromSchemaChildren(xmlSchema, complexTypeNode, complexTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return complexTypeNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getComplexTypeNameFromChildren(Node localComplexTypeRootNode,
|
||||||
|
String elementNameWithoutNamespace) {
|
||||||
|
NodeList list = localComplexTypeRootNode.getChildNodes();
|
||||||
|
String complexTypeName = "";
|
||||||
|
|
||||||
|
for(int i=0; i< list.getLength();i++) {
|
||||||
|
Node node = list.item(i);
|
||||||
|
if ( node instanceof Element) {
|
||||||
|
if (node.getLocalName().equals("element")) {
|
||||||
|
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||||
|
if (nameAttribute.getNodeValue().equals(elementNameWithoutNamespace)) {
|
||||||
|
Node complexTypeAttribute = node.getAttributes().getNamedItem("type");
|
||||||
|
if (complexTypeAttribute!=null) {
|
||||||
|
complexTypeName = complexTypeAttribute.getNodeValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return complexTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getComplexTypeNodeFromSchemaChildren(Node xmlSchema, Node complexTypeNode,
|
||||||
|
String complexTypeName) {
|
||||||
|
NodeList complexTypeList = xmlSchema.getChildNodes();
|
||||||
|
for(int i=0; i< complexTypeList.getLength();i++) {
|
||||||
|
Node node = complexTypeList.item(i);
|
||||||
|
if ( node instanceof Element) {
|
||||||
|
if (node.getLocalName().equals("complexType")) {
|
||||||
|
Node nameAttribute = node.getAttributes().getNamedItem("name");
|
||||||
|
if (nameAttribute.getNodeValue().equals(complexTypeName)) {
|
||||||
|
|
||||||
|
NodeList complexTypeChildList =node.getChildNodes();
|
||||||
|
for(int j=0; j<complexTypeChildList.getLength();j++) {
|
||||||
|
Node sequence = complexTypeChildList.item(j);
|
||||||
|
|
||||||
|
if ( sequence instanceof Element) {
|
||||||
|
if (sequence.getLocalName().equals("sequence")) {
|
||||||
|
complexTypeNode = sequence;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (complexTypeNode!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return complexTypeNode;
|
||||||
|
}
|
||||||
|
}
|
@ -361,6 +361,40 @@ public final class TestXSSFExportToXML extends TestCase {
|
|||||||
assertTrue(found);
|
assertTrue(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testXmlExportSchemaWithXSAllTag_Bugzilla_56169() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56169.xlsx");
|
||||||
|
|
||||||
|
for (XSSFMap map : wb.getCustomXMLMappings()) {
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertTrue(!xmlData.equals(""));
|
||||||
|
|
||||||
|
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
|
||||||
|
String a_b = a.split("<B>")[1].split("</B>")[0].trim();
|
||||||
|
String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
|
||||||
|
String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
|
||||||
|
String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("1", a_b_c_e_euro);
|
||||||
|
assertEquals("2", a_b_c_e_chf);
|
||||||
|
|
||||||
|
String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
|
||||||
|
String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
|
||||||
|
|
||||||
|
String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("3", a_b_d_e_euro);
|
||||||
|
assertEquals("4", a_b_d_e_chf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testXmlExportCompare_Bug_55923() throws Exception {
|
public void testXmlExportCompare_Bug_55923() throws Exception {
|
||||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
||||||
|
|
||||||
|
@ -0,0 +1,548 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.xssf.extractor;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLDocumentPart;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||||
|
import org.apache.poi.xssf.model.MapInfo;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFMap;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xml.sax.EntityResolver;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roberto Manicardi
|
||||||
|
*/
|
||||||
|
public final class TestXSSFExportToXML extends TestCase {
|
||||||
|
public void testExportToXML() throws Exception {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xml = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xml);
|
||||||
|
assertFalse(xml.equals(""));
|
||||||
|
|
||||||
|
String docente = xml.split("<DOCENTE>")[1].split("</DOCENTE>")[0].trim();
|
||||||
|
String nome = xml.split("<NOME>")[1].split("</NOME>")[0].trim();
|
||||||
|
String tutor = xml.split("<TUTOR>")[1].split("</TUTOR>")[0].trim();
|
||||||
|
String cdl = xml.split("<CDL>")[1].split("</CDL>")[0].trim();
|
||||||
|
String durata = xml.split("<DURATA>")[1].split("</DURATA>")[0].trim();
|
||||||
|
String argomento = xml.split("<ARGOMENTO>")[1].split("</ARGOMENTO>")[0].trim();
|
||||||
|
String progetto = xml.split("<PROGETTO>")[1].split("</PROGETTO>")[0].trim();
|
||||||
|
String crediti = xml.split("<CREDITI>")[1].split("</CREDITI>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("ro", docente);
|
||||||
|
assertEquals("ro", nome);
|
||||||
|
assertEquals("ds", tutor);
|
||||||
|
assertEquals("gs", cdl);
|
||||||
|
assertEquals("g", durata);
|
||||||
|
assertEquals("gvvv", argomento);
|
||||||
|
assertEquals("aaaa", progetto);
|
||||||
|
assertEquals("aa", crediti);
|
||||||
|
|
||||||
|
parseXML(xml);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExportToXMLInverseOrder() throws Exception {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples
|
||||||
|
.openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx");
|
||||||
|
|
||||||
|
MapInfo mapInfo = null;
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xml = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xml);
|
||||||
|
assertFalse(xml.equals(""));
|
||||||
|
|
||||||
|
String docente = xml.split("<DOCENTE>")[1].split("</DOCENTE>")[0].trim();
|
||||||
|
String nome = xml.split("<NOME>")[1].split("</NOME>")[0].trim();
|
||||||
|
String tutor = xml.split("<TUTOR>")[1].split("</TUTOR>")[0].trim();
|
||||||
|
String cdl = xml.split("<CDL>")[1].split("</CDL>")[0].trim();
|
||||||
|
String durata = xml.split("<DURATA>")[1].split("</DURATA>")[0].trim();
|
||||||
|
String argomento = xml.split("<ARGOMENTO>")[1].split("</ARGOMENTO>")[0].trim();
|
||||||
|
String progetto = xml.split("<PROGETTO>")[1].split("</PROGETTO>")[0].trim();
|
||||||
|
String crediti = xml.split("<CREDITI>")[1].split("</CREDITI>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("aa", nome);
|
||||||
|
assertEquals("aaaa", docente);
|
||||||
|
assertEquals("gvvv", tutor);
|
||||||
|
assertEquals("g", cdl);
|
||||||
|
assertEquals("gs", durata);
|
||||||
|
assertEquals("ds", argomento);
|
||||||
|
assertEquals("ro", progetto);
|
||||||
|
assertEquals("ro", crediti);
|
||||||
|
|
||||||
|
parseXML(xml);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testXPathOrdering() {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples
|
||||||
|
.openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx");
|
||||||
|
|
||||||
|
MapInfo mapInfo = null;
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (p instanceof MapInfo) {
|
||||||
|
mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
|
||||||
|
assertEquals(1, exporter.compare("/CORSO/DOCENTE", "/CORSO/NOME"));
|
||||||
|
assertEquals(-1, exporter.compare("/CORSO/NOME", "/CORSO/DOCENTE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiTable() throws Exception {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples
|
||||||
|
.openSampleWorkbook("CustomXMLMappings-complex-type.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (p instanceof MapInfo) {
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(2);
|
||||||
|
|
||||||
|
assertNotNull(map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xml = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xml);
|
||||||
|
|
||||||
|
String[] regexConditions = {
|
||||||
|
"<MapInfo", "</MapInfo>",
|
||||||
|
"<Schema ID=\"1\" Namespace=\"\" SchemaRef=\"\"/>",
|
||||||
|
"<Schema ID=\"4\" Namespace=\"\" SchemaRef=\"\"/>",
|
||||||
|
"DataBinding",
|
||||||
|
"Map Append=\"false\" AutoFit=\"false\" ID=\"1\"",
|
||||||
|
"Map Append=\"false\" AutoFit=\"false\" ID=\"5\"",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String condition : regexConditions) {
|
||||||
|
Pattern pattern = Pattern.compile(condition);
|
||||||
|
Matcher matcher = pattern.matcher(xml);
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test55850ComplexXmlExport() throws Exception {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples
|
||||||
|
.openSampleWorkbook("55850.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(2);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
|
||||||
|
String b = a.split("<B>")[1].split("</B>")[0].trim();
|
||||||
|
String c = b.split("<C>")[1].split("</C>")[0].trim();
|
||||||
|
String d = c.split("<D>")[1].split("</Dd>")[0].trim();
|
||||||
|
String e = d.split("<E>")[1].split("</EA>")[0].trim();
|
||||||
|
|
||||||
|
String euro = e.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
String chf = e.split("<CHF>")[1].split("</CHF>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("15", euro);
|
||||||
|
assertEquals("19", chf);
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFormulaCells_Bugzilla_55927() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55927.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
String date = xmlData.split("<DATE>")[1].split("</DATE>")[0].trim();
|
||||||
|
assertEquals("2012-01-13", date);
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFormulaCells_Bugzilla_55926() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55926.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
|
||||||
|
String doubleValue = a.split("<DOUBLE>")[1].split("</DOUBLE>")[0].trim();
|
||||||
|
String stringValue = a.split("<STRING>")[1].split("</STRING>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("Hello World", stringValue);
|
||||||
|
assertEquals("5.1", doubleValue);
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXmlExportIgnoresEmptyCells_Bugzilla_55924() throws Exception {
|
||||||
|
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55924.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(1);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
|
||||||
|
String euro = a.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
assertEquals("1",euro);
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testXmlExportCompare_Bug_55923() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(4);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
assertEquals(0, exporter.compare("", ""));
|
||||||
|
assertEquals(0, exporter.compare("/", "/"));
|
||||||
|
assertEquals(0, exporter.compare("//", "//"));
|
||||||
|
assertEquals(0, exporter.compare("/a/", "/b/"));
|
||||||
|
|
||||||
|
assertEquals(-1, exporter.compare("/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:EUR",
|
||||||
|
"/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:CHF"));
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testXmlExportSchemaOrderingBug_Bugzilla_55923() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(4);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
|
||||||
|
String a_b = a.split("<B>")[1].split("</B>")[0].trim();
|
||||||
|
String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
|
||||||
|
String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
|
||||||
|
String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("1",a_b_c_e_euro);
|
||||||
|
assertEquals("2",a_b_c_e_chf);
|
||||||
|
|
||||||
|
String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
|
||||||
|
String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
|
||||||
|
|
||||||
|
String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
|
||||||
|
String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
|
||||||
|
|
||||||
|
assertEquals("3",a_b_d_e_euro);
|
||||||
|
assertEquals("4",a_b_d_e_chf);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseXML(String xmlData) throws IOException, SAXException, ParserConfigurationException {
|
||||||
|
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
docBuilderFactory.setNamespaceAware(true);
|
||||||
|
docBuilderFactory.setValidating(false);
|
||||||
|
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
|
||||||
|
docBuilder.setEntityResolver(new DummyEntityResolver());
|
||||||
|
|
||||||
|
docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes("UTF-8")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DummyEntityResolver implements EntityResolver
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExportDataTypes() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
||||||
|
|
||||||
|
Sheet sheet = wb.getSheetAt(0);
|
||||||
|
Row row = sheet.getRow(0);
|
||||||
|
|
||||||
|
Cell cString = row.createCell(0);
|
||||||
|
cString.setCellValue("somestring");
|
||||||
|
cString.setCellType(XSSFCell.CELL_TYPE_STRING);
|
||||||
|
|
||||||
|
Cell cBoolean = row.createCell(1);
|
||||||
|
cBoolean.setCellValue(true);
|
||||||
|
cBoolean.setCellType(XSSFCell.CELL_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
Cell cError = row.createCell(2);
|
||||||
|
cError.setCellType(XSSFCell.CELL_TYPE_ERROR);
|
||||||
|
|
||||||
|
Cell cFormulaString = row.createCell(3);
|
||||||
|
cFormulaString.setCellFormula("A1");
|
||||||
|
cFormulaString.setCellType(XSSFCell.CELL_TYPE_FORMULA);
|
||||||
|
|
||||||
|
Cell cFormulaNumeric = row.createCell(4);
|
||||||
|
cFormulaNumeric.setCellFormula("F1");
|
||||||
|
cFormulaNumeric.setCellType(XSSFCell.CELL_TYPE_FORMULA);
|
||||||
|
|
||||||
|
Cell cNumeric = row.createCell(5);
|
||||||
|
cNumeric.setCellValue(1.2);
|
||||||
|
cNumeric.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
|
||||||
|
|
||||||
|
Cell cDate = row.createCell(6);
|
||||||
|
cDate.setCellValue(new Date());
|
||||||
|
cDate.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(4);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, true);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testValidateFalse() throws Exception {
|
||||||
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (POIXMLDocumentPart p : wb.getRelations()) {
|
||||||
|
|
||||||
|
if (!(p instanceof MapInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MapInfo mapInfo = (MapInfo) p;
|
||||||
|
|
||||||
|
XSSFMap map = mapInfo.getXSSFMapById(4);
|
||||||
|
|
||||||
|
assertNotNull("XSSFMap is null", map);
|
||||||
|
|
||||||
|
XSSFExportToXml exporter = new XSSFExportToXml(map);
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
exporter.exportToXML(os, false);
|
||||||
|
String xmlData = os.toString("UTF-8");
|
||||||
|
|
||||||
|
assertNotNull(xmlData);
|
||||||
|
assertFalse(xmlData.equals(""));
|
||||||
|
|
||||||
|
parseXML(xmlData);
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user