Skip to Content.
Sympa Menu

xom-interest - Re: [XOM-interest] Element. // Used for XPath and serialization Why is Element.getNamespacePrefixesInScope() private?

xom-interest AT lists.ibiblio.org

Subject: XOM API for Processing XML with Java

List archive

Chronological Thread  
  • From: Wolfgang Hoschek <wolfgang.hoschek AT mac.com>
  • To: Elliotte Harold <elharo AT metalab.unc.edu>
  • Cc: xom-interest <xom-interest AT lists.ibiblio.org>
  • Subject: Re: [XOM-interest] Element. // Used for XPath and serialization Why is Element.getNamespacePrefixesInScope() private?
  • Date: Mon, 23 Jan 2006 15:28:05 -0800


On Jan 23, 2006, at 9:43 AM, Elliotte Harold wrote:

Steve Loughran wrote:

Can I observe that the implementation of getNamespacePrefix(int) and
getNamespaceDeclarationCount() are both, well, aggressively suboptimal
as they create set structures that are discarded every run. That would
make enumerating all the namespaces an O(n*n) kind of process, rather
than the more simpler O(n) operation that would appear to be possible.

[snip]

Until someone proves me wrong by presenting such a use case, I remain
convinced that iterating over all the namespaces of an element, either
in-scope or declared, is a very strange thing to want to do and far
beyond the 80-20 point.

Anything that converts an external XML representation from/to XOM requires efficient support for namespace iterations. Like the nu.xom.Serializer or DOMConverter or SAXConverter, or the streaming serializers, the bnux serializer or the STAX converters, or any number of other things connecting to Axis AXIOM, XFire, JAXB, JixB, etc, etc.

Like it or not, XOM has zero chance of long term survival if there are no straightforward and efficient means to integrate it with the myriad of other non-XOM based XML tools.

Since it is possible to iterate over namespaces
in XOM, I have no desire to complicate the API just to make it faster.

Converting XML representation A to B is the number one use case where efficiency really matters.

For example, how come it's OK for the nu.xom.Serializer to use private loopholes go gain access to package level internals, if not for the sake of efficiency? Cause that's precisely what it's doing. Same question for the XPath impl?

While we're at it, you could further improve the Serializer efficiency. Consider Serializer.writeNamespaceDeclarations(Element element):

There's no need to fill a map with entries via the element.getNamespaces() loophole. You could separately iterate over element.namespaces.namespaces and the element's attributes and the elements own namespaces. Testing the stack for an existing ns mapping would remain essentially the same, taking care of things like "xml" prefixes and such.

Instead of using a loophole, one way to publicly expose element.namespaces.namespaces in an efficient, clean and safe way would be via Element.getAdditionalNamespaceDeclarations(), or similar:

private static final String[] EMPTY = new String[0];

/**
*Returnsalistof(prefix,URI)pairsintheformprefix0,uri0,...,
*prefixN,uriN,oranemptyarrayiftherearenoadditionalnamespace
*declarationsonthiselement.
*/
public final String[] getAdditionalNamespaceDeclarations() { // WH
if (namespaces == null) return EMPTY;
ArrayList prefixes = namespaces.getPrefixes();
int size = prefixes.size();
if (size == 0) return EMPTY;
String[] results = new String[2 * size];
for (int i=0, j=0; i < size; i++, j += 2) {
results[j+0] = (String) prefixes.get(i);
results[j+1] = namespaces.getURI(results[j]);
}
return results;
}

There could be alternative approaches in dealing with the problem, perhaps somewhat similar to the NamespacesInScope.Iterator, exposing a variety of common low-level namespace iterations in a typesafe and efficient manner.

It's indeed not clear which approach would be best, but it's entirely obvious that there's currently a serious problem here, and ignoring it certainly won't help.

Wolfgang.




Archive powered by MHonArc 2.6.24.

Top of Page