import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.helpers.XSSFSingleXmlCell;
import org.apache.poi.xssf.usermodel.helpers.XSSFXmlColumnPr;
-import org.apache.xml.utils.PrefixResolver;
-import org.apache.xml.utils.PrefixResolverDefault;
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.InputSource;
import org.xml.sax.SAXException;
/**
- *
* Imports data from an external XML to an XLSX according to one of the mappings
* defined.The output XML Schema must respect this limitations:
* <ul>
*/
public class XSSFImportFromXML {
- private XSSFMap map;
+ private final XSSFMap _map;
private static POILogger logger = POILogFactory.getLogger(XSSFImportFromXML.class);
public XSSFImportFromXML(XSSFMap map) {
- this.map = map;
+ _map = map;
}
/**
* Imports an XML into the XLSX using the Custom XML mapping defined
- *
+ *
* @param xmlInputString the XML to import
* @throws SAXException if error occurs during XML parsing
* @throws XPathExpressionException if error occurs during XML navigation
- * @throws ParserConfigurationException if there are problems with XML parser configuration
+ * @throws ParserConfigurationException if there are problems with XML parser configuration
* @throws IOException if there are problems reading the input string
*/
public void importFromXML(String xmlInputString) throws SAXException, XPathExpressionException, ParserConfigurationException, IOException {
Document doc = builder.parse(new InputSource(new StringReader(xmlInputString.trim())));
- List<XSSFSingleXmlCell> singleXmlCells = map.getRelatedSingleXMLCell();
+ List<XSSFSingleXmlCell> singleXmlCells = _map.getRelatedSingleXMLCell();
- List<Table> tables = map.getRelatedTables();
+ List<Table> tables = _map.getRelatedTables();
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
// Setting namespace context to XPath
// Assuming that the namespace prefix in the mapping xpath is the
// same as the one used in the document
- final PrefixResolver resolver = new PrefixResolverDefault(doc.getDocumentElement());
-
- NamespaceContext ctx = new NamespaceContext() {
-
- public String getNamespaceURI(String prefix) {
- return resolver.getNamespaceForPrefix(prefix);
- }
-
- // Dummy implementation - not used!
- public Iterator getPrefixes(String val) {
- return null;
- }
-
- // Dummy implemenation - not used!
- public String getPrefix(String uri) {
- return null;
- }
- };
- xpath.setNamespaceContext(ctx);
+ xpath.setNamespaceContext(new DefaultNamespaceContext(doc));
for (XSSFSingleXmlCell singleXmlCell : singleXmlCells) {
logger.log(POILogger.DEBUG, "Setting '" + value + "' to cell " + cell.getColumnIndex() + "-" + cell.getRowIndex() + " in sheet "
+ table.getXSSFSheet().getSheetName());
cell.setCellValue(value.trim());
-
}
+ }
+ }
+ }
+
+ private static final class DefaultNamespaceContext implements NamespaceContext {
+ /**
+ * Node from which to start searching for a xmlns attribute that binds a
+ * prefix to a namespace.
+ */
+ private final Element _docElem;
+
+ public DefaultNamespaceContext(Document doc) {
+ _docElem = doc.getDocumentElement();
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return getNamespaceForPrefix(prefix);
+ }
+ /**
+ * @param prefix Prefix to resolve.
+ * @return uri of Namespace that prefix resolves to, or
+ * <code>null</code> if specified prefix is not bound.
+ */
+ private String getNamespaceForPrefix(String prefix) {
+
+ // Code adapted from Xalan's org.apache.xml.utils.PrefixResolverDefault.getNamespaceForPrefix()
+
+ if (prefix.equals("xml")) {
+ return "http://www.w3.org/XML/1998/namespace";
}
+ Node parent = _docElem;
+
+ while (parent != null) {
+
+ int type = parent.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ if (parent.getNodeName().startsWith(prefix + ":")) {
+ return parent.getNamespaceURI();
+ }
+ NamedNodeMap nnm = parent.getAttributes();
+
+ for (int i = 0; i < nnm.getLength(); i++) {
+ Node attr = nnm.item(i);
+ String aname = attr.getNodeName();
+ boolean isPrefix = aname.startsWith("xmlns:");
+
+ if (isPrefix || aname.equals("xmlns")) {
+ int index = aname.indexOf(':');
+ String p = isPrefix ? aname.substring(index + 1) : "";
+
+ if (p.equals(prefix)) {
+ return attr.getNodeValue();
+ }
+ }
+ }
+ } else if (type == Node.ENTITY_REFERENCE_NODE) {
+ continue;
+ } else {
+ break;
+ }
+ parent = parent.getParentNode();
+ }
+
+ return null;
}
+ // Dummy implementation - not used!
+ public Iterator getPrefixes(String val) {
+ return null;
+ }
+
+ // Dummy implementation - not used!
+ public String getPrefix(String uri) {
+ return null;
+ }
}
}
+++ /dev/null
-/*
- * 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.
- */
-/*
- * $Id$
- */
-package org.apache.xml.utils;
-
-/**
- * The class that implements this interface can resolve prefixes to
- * namespaces. Examples would include resolving the meaning of a
- * prefix at a particular point in a document, or mapping the prefixes
- * used in an XPath expression.
- * @xsl.usage advanced
- */
-public interface PrefixResolver
-{
-
- /**
- * Given a namespace, get the corrisponding prefix. This assumes that
- * the PrefixResolver holds its own namespace context, or is a namespace
- * context itself.
- *
- * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
- *
- * @return The associated Namespace URI, or null if the prefix
- * is undeclared in this context.
- */
- String getNamespaceForPrefix(String prefix);
-
- /**
- * Given a namespace, get the corresponding prefix, based on the context node.
- *
- * @param prefix The prefix to look up, which may be an empty string ("") for the default Namespace.
- * @param context The node context from which to look up the URI.
- *
- * @return The associated Namespace URI as a string, or null if the prefix
- * is undeclared in this context.
- */
- String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context);
-
- /**
- * Return the base identifier.
- *
- * @return The base identifier from where relative URIs should be absolutized, or null
- * if the base ID is unknown.
- * <p>
- * CAVEAT: Note that the base URI in an XML document may vary with where
- * you are in the document, if part of the doc's contents were brought in
- * via an external entity reference or if mechanisms such as xml:base have
- * been used. Unless this PrefixResolver is bound to a specific portion of
- * the document, or has been kept up to date via some other mechanism, it
- * may not accurately reflect that context information.
- */
- public String getBaseIdentifier();
-
- public boolean handlesNullPrefixes();
-}
+++ /dev/null
-/*
- * 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.
- */
-/*
- * $Id$
- */
-package org.apache.xml.utils;
-
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-/**
- * This class implements a generic PrefixResolver that
- * can be used to perform prefix-to-namespace lookup
- * for the XPath object.
- * @xsl.usage general
- */
-public class PrefixResolverDefault implements PrefixResolver
-{
-
- public static final java.lang.String S_XMLNAMESPACEURI = "http://www.w3.org/XML/1998/namespace";
-
- /**
- * The context to resolve the prefix from, if the context
- * is not given.
- */
- Node m_context;
-
- /**
- * Construct a PrefixResolverDefault object.
- * @param xpathExpressionContext The context from
- * which XPath expression prefixes will be resolved.
- * Warning: This will not work correctly if xpathExpressionContext
- * is an attribute node.
- */
- public PrefixResolverDefault(Node xpathExpressionContext)
- {
- m_context = xpathExpressionContext;
- }
-
- /**
- * Given a namespace, get the corrisponding prefix. This assumes that
- * the PrevixResolver hold's it's own namespace context, or is a namespace
- * context itself.
- * @param prefix Prefix to resolve.
- * @return Namespace that prefix resolves to, or null if prefix
- * is not bound.
- */
- public String getNamespaceForPrefix(String prefix)
- {
- return getNamespaceForPrefix(prefix, m_context);
- }
-
- /**
- * Given a namespace, get the corrisponding prefix.
- * Warning: This will not work correctly if namespaceContext
- * is an attribute node.
- * @param prefix Prefix to resolve.
- * @param namespaceContext Node from which to start searching for a
- * xmlns attribute that binds a prefix to a namespace.
- * @return Namespace that prefix resolves to, or null if prefix
- * is not bound.
- */
- public String getNamespaceForPrefix(String prefix,
- org.w3c.dom.Node namespaceContext)
- {
-
- Node parent = namespaceContext;
- String namespace = null;
-
- if (prefix.equals("xml"))
- {
- namespace = S_XMLNAMESPACEURI;
- }
- else
- {
- int type;
-
- while ((null != parent) && (null == namespace)
- && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
- || (type == Node.ENTITY_REFERENCE_NODE)))
- {
- if (type == Node.ELEMENT_NODE)
- {
- if (parent.getNodeName().indexOf(prefix+":") == 0)
- return parent.getNamespaceURI();
- NamedNodeMap nnm = parent.getAttributes();
-
- for (int i = 0; i < nnm.getLength(); i++)
- {
- Node attr = nnm.item(i);
- String aname = attr.getNodeName();
- boolean isPrefix = aname.startsWith("xmlns:");
-
- if (isPrefix || aname.equals("xmlns"))
- {
- int index = aname.indexOf(':');
- String p = isPrefix ? aname.substring(index + 1) : "";
-
- if (p.equals(prefix))
- {
- namespace = attr.getNodeValue();
-
- break;
- }
- }
- }
- }
-
- parent = parent.getParentNode();
- }
- }
-
- return namespace;
- }
-
- /**
- * Return the base identifier.
- *
- * @return null
- */
- public String getBaseIdentifier()
- {
- return null;
- }
- /**
- * @see PrefixResolver#handlesNullPrefixes()
- */
- public boolean handlesNullPrefixes() {
- return false;
- }
-
-}