if (DEBUG) System.err.println("converting element=" + node.getDisplayName());
Element elem = new Element(node.getDisplayName(), node.getURI());
NodeInfo next;
// Append attributes
AxisIterator iter = node.iterateAxis(Axis.ATTRIBUTE);
ArrayList prefixes = null;
while ((next = (NodeInfo) iter.next()) != null) {
elem.addAttribute((Attribute) convertNodeInfo(next));
// keep track of attributes with prefixes, so we can avoid adding costly
// additional namespaces declarations below. This safes potentially vast
// amounts of memory due too XOM's expensive NS declaration storage scheme.
String prefix = next.getPrefix();
if (prefix.length() != 0) { // e.g. SOAP
if (prefixes == null) prefixes = new ArrayList(1);
prefixes.add(prefix);
}
}
// Append namespace declarations (avoids unnecessary redeclarations).
// For background see net.sf.saxon.om.NamespaceIterator and
// net.sf.saxon.om.NamespaceDeclarationsImpl
int[] namespaces = node.getDeclaredNamespaces(NodeInfo.EMPTY_NAMESPACE_LIST);
int i = 0;
int nsCode;
NamePool pool = null;
while (i < namespaces.length && (nsCode = namespaces[i]) != -1) {
short uriCode = (short) (nsCode & 0xffff);
if (uriCode != 0) { // it is not an undeclaration
if (pool == null) pool = node.getNamePool();
String uri = pool.getURIFromURICode(uriCode);
String prefix = pool.getPrefixFromNamespaceCode(nsCode);
if (prefixes != null && prefixes.contains(prefix)) {
if (DEBUG) System.err.println(
"Safely ignoring additional namespace declaration for prefix="
+ prefix + ", uri=" + uri);
}
else {
if (DEBUG) System.err.println(
"Adding additional namespace declaration for prefix="
+ prefix + ", uri=" + uri);
elem.addNamespaceDeclaration(prefix, uri);
}
}
i++;
}
prefixes = null; // help gc
namespaces = null; // help gc
// // Append namespace declarations (would introduce lots of redundant redeclarations)
// iter = node.iterateAxis(Axis.NAMESPACE);
// while ((next = (NodeInfo) iter.next()) != null) {
// String prefix = next.getLocalPart();
// String uri = next.getStringValue();
// if (DEBUG) System.err.println("converted prefix=" + prefix + ", uri=" + uri);
// elem.addNamespaceDeclaration(prefix, uri);
// }
// Append children (recursively)
iter = node.iterateAxis(Axis.CHILD);
while ((next = (NodeInfo) iter.next()) != null) {
elem.appendChild(convertNodeInfo(next));
}
return elem;
}