diff --git a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
index 04272e36c..66209ed61 100644
--- a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
+++ b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
@@ -74,441 +74,435 @@ import org.xml.sax.SAXException;
*
no mixed content: an element can't contain simple text and child element(s) together
* no <substitutionGroup> in complex type/element declaration
*
- *
- * @author Roberto Manicardi
*/
public class XSSFExportToXml implements Comparator{
- 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;
- }
+ 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 validate if true, validates the XML againts the XML Schema
- * @throws SAXException
- */
- public void exportToXML(OutputStream os, boolean validate) throws SAXException{
- exportToXML(os,"UTF-8", validate);
- }
+ /**
+ * 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 singleXMLCells = map.getRelatedSingleXMLCell();
+ List tables = map.getRelatedTables();
- private Document getEmptyDocument() throws ParserConfigurationException{
-
- DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
- Document doc = docBuilder.newDocument();
+ String rootElement = map.getCtMap().getRootElement();
- return doc;
- }
+ Document doc = getEmptyDocument();
- /**
- * 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 InvalidFormatException
- */
- public void exportToXML(OutputStream os, String encoding, boolean validate) throws SAXException{
- List singleXMLCells = map.getRelatedSingleXMLCell();
- List tables = map.getRelatedTables();
+ Element root = null;
- String rootElement = map.getCtMap().getRootElement();
+ if (isNamespaceDeclared()) {
+ root=doc.createElementNS(getNamespace(),rootElement);
+ } else {
+ root=doc.createElement(rootElement);
+ }
+ doc.appendChild(root);
- try{
- Document doc = getEmptyDocument();
+ List xpaths = new Vector();
+ Map singleXmlCellsMappings = new HashMap();
+ Map tableMappings = new HashMap();
- Element root = null;
+ for(XSSFSingleXmlCell simpleXmlCell : singleXMLCells) {
+ xpaths.add(simpleXmlCell.getXpath());
+ singleXmlCellsMappings.put(simpleXmlCell.getXpath(), simpleXmlCell);
+ }
+ for(Table table : tables) {
+ String commonXPath = table.getCommonXpath();
+ xpaths.add(commonXPath);
+ tableMappings.put(commonXPath, table);
+ }
- if (isNamespaceDeclared()) {
- root=doc.createElementNS(getNamespace(),rootElement);
- } else {
- root=doc.createElement(rootElement);
- }
- doc.appendChild(root);
+ Collections.sort(xpaths,this);
- List xpaths = new Vector();
- Map singleXmlCellsMappings = new HashMap();
- Map tableMappings = new HashMap();
+ for(String xpath : xpaths) {
- for(XSSFSingleXmlCell simpleXmlCell : singleXMLCells) {
- xpaths.add(simpleXmlCell.getXpath());
- singleXmlCellsMappings.put(simpleXmlCell.getXpath(), simpleXmlCell);
- }
- for(Table table : tables) {
- String commonXPath = table.getCommonXpath();
- xpaths.add(commonXPath);
- tableMappings.put(commonXPath, table);
- }
+ XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath);
+ Table table = tableMappings.get(xpath);
+ if (!xpath.matches(".*\\[.*")) {
- Collections.sort(xpaths,this);
+ // 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);
+ }
+ }
- for(String xpath : xpaths) {
+ // Exports elements and attributes mapped with tables
+ if (table!=null) {
- XSSFSingleXmlCell simpleXmlCell = singleXmlCellsMappings.get(xpath);
- Table table = tableMappings.get(xpath);
+ List tableColumns = table.getXmlColumnPrs();
- if (!xpath.matches(".*\\[.*")) {
+ XSSFSheet sheet = table.getXSSFSheet();
- // 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);
- }
- }
+ int startRow = table.getStartCellReference().getRow();
+ // In mappings created with Microsoft Excel the first row contains the table header and must be skipped
+ startRow +=1;
- // Exports elements and attributes mapped with tables
- if (table!=null) {
+ int endRow = table.getEndCellReference().getRow();
- List tableColumns = table.getXmlColumnPrs();
+ for(int i = startRow; i<= endRow; i++) {
+ XSSFRow row = sheet.getRow(i);
- XSSFSheet sheet = table.getXSSFSheet();
+ Node tableRootNode = getNodeByXPath(table.getCommonXpath(),doc.getFirstChild(),doc,true);
- int startRow = table.getStartCellReference().getRow();
- // In mappings created with Microsoft Excel the first row contains the table header and must be skipped
- startRow +=1;
+ 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();
- int endRow = table.getEndCellReference().getRow();
- for(int i = startRow; i<= endRow; i++) {
- XSSFRow row = sheet.getRow(i);
+ mapCellOnNode(cell,currentNode,dataType);
+ }
- 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);
+ }
- }
- } else {
- // TODO: implement filtering management in xpath
- }
- }
+ if (isValid) {
- boolean isValid = true;
- if (validate) {
- isValid =isValid(doc);
- }
+ /////////////////
+ //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
- if (isValid) {
+ StreamResult result = new StreamResult(os);
+ DOMSource source = new DOMSource(doc);
+ trans.transform(source, result);
- /////////////////
- //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
+ /**
+ * Validate the generated XML against the XML Schema associated with the XSSFMap
+ *
+ * @param xml the XML to validate
+ * @return
+ */
+ private boolean isValid(Document xml) throws SAXException{
+ boolean isValid = false;
+ try{
+ String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ SchemaFactory factory = SchemaFactory.newInstance(language);
- StreamResult result = new StreamResult(os);
- DOMSource source = new DOMSource(doc);
- trans.transform(source, result);
+ 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(ParserConfigurationException e) {
- e.printStackTrace();
- }catch(TransformerException e) {
- e.printStackTrace();
- }
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ return isValid;
+ }
- }
- /**
- * Validate the generated XML against the XML Schema associated with the XSSFMap
- *
- * @param xml the XML to validate
- * @return
- */
- private boolean isValid(Document xml) throws SAXException{
- boolean isValid = false;
- try{
- String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
- SchemaFactory factory = SchemaFactory.newInstance(language);
+ private void mapCellOnNode(XSSFCell cell, Node node, STXmlDataType.Enum outputDataType) {
- 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;
+ 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: value = cell.getStringCellValue(); break;
+ case XSSFCell.CELL_TYPE_NUMERIC: value += cell.getRawValue(); break;
+ default: ;
- } catch(IOException e) {
- e.printStackTrace();
- }
- return isValid;
- }
+ }
+ 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 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: value = cell.getStringCellValue(); break;
- case XSSFCell.CELL_TYPE_NUMERIC: value += cell.getRawValue(); break;
- default: ;
+ private Node getNodeByXPath(String xpath,Node rootNode,Document doc,boolean createMultipleInstances) {
+ String[] xpathTokens = xpath.split("/");
- }
- 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;
- }
+ Node currentNode =rootNode;
+ // The first token is empty, the second is the root node
+ for(int i =2; i rightIndex) {
- result = 1;
- }
- } else {
- // NOTE: the xpath doesn't match correctly in the schema
- }
- }
- }
-
- return result;
- }
-
- 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) {
- Node complexTypeNode = null;
-
- String elementNameWithoutNamespace = removeNamespace(elementName);
-
-
- 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;
- }
- }
- }
- }
- }
- // Note: we expect that all the complex types are defined at root level
- if (!"".equals(complexTypeName)) {
- NodeList complexTypeList = xmlSchema.getChildNodes();
- for(int i=0; i< complexTypeList.getLength();i++) {
- Node node = list.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 rightIndex) {
+ result = 1;
+ }
+ } else {
+ // NOTE: the xpath doesn't match correctly in the schema
+ }
+ }
+ }
+
+ return result;
+ }
+
+ 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) {
+ Node complexTypeNode = null;
+
+ String elementNameWithoutNamespace = removeNamespace(elementName);
+
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+ // Note: we expect that all the complex types are defined at root level
+ if (!"".equals(complexTypeName)) {
+ NodeList complexTypeList = xmlSchema.getChildNodes();
+ for(int i=0; i< complexTypeList.getLength();i++) {
+ Node node = list.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