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:
Dominik Stadler 2014-03-15 17:29:17 +00:00
parent f597633624
commit 7c3f1a926b
4 changed files with 1123 additions and 6 deletions

View File

@ -261,7 +261,6 @@ public class XSSFExportToXml implements Comparator<String>{
* @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);
@ -270,14 +269,14 @@ public class XSSFExportToXml implements Comparator<String>{
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;
return true;
} catch(IOException e) {
e.printStackTrace();
}
return isValid;
return false;
}
@ -517,7 +516,7 @@ public class XSSFExportToXml implements Comparator<String>{
Node sequence = complexTypeChildList.item(j);
if ( sequence instanceof Element) {
if (sequence.getLocalName().equals("sequence")) {
if (sequence.getLocalName().equals("sequence") || sequence.getLocalName().equals("all")) {
complexTypeNode = sequence;
break;
}

View File

@ -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 &lt;any&gt; in complex type/element declaration </li>
* <li> no &lt;anyAttribute&gt; 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 &lt;substitutionGroup&gt; 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;
}
}

View File

@ -361,6 +361,40 @@ public final class TestXSSFExportToXML extends TestCase {
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 {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx");

View File

@ -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);
}
}