Chapter 4 XML Processing
191
face. Implementing this interface enables you to retrieve the resources referred
to in the style sheets by the
xsl:import
or
xsl:include
statements. For an ap
plication using a large set of componentized style sheets, this may be used to
implement a cache in much the same way as the
EntityResolver
. You can use
EntityResolver
and
URIResolver
to implement:
I
A caching mechanism in the application itself, or
I
A custom URI lookup mechanism that may redirect system and public refer
ences to a local copy of a public repository.
You can use both caching approaches together to ensure even better perfor
mance. Use a proxy cache for static entities whose lifetime is greater than the
application's lifetime. This particularly works with public schemas, which include
the version number in their public or system identifier, since they evolve through
successive versions. A custom entity resolver may first map public identifiers
(usually in the form of a URI) into system identifiers (usually in the form of an
URL). Afterwards, it applies the same techniques as a regular cache proxy when
dealing with system identifiers in the form of an URL, especially checking for
updates and avoiding caching dynamic content. Using these caching approaches
often results in a significant performance improvement, especially when external
entities are located on the network. Code Example 4.13 illustrates how to
implement a caching entity resolver using the SAX API.
import java.util.Map;
import java.util.WeakHashMap;
import java.lang.ref.SoftReference;
import org.xml.sax.*;
public class CachingEntityResolver implements EntityResolver {
public static final int MAX_CACHE_ENTRY_SIZE = ...;
private EntityResolver parentResolver;
private Map entities = new WeakHashMap();
static private class Entity {
String name;
byte[] content;
}
public CachingEntityResolver(EntityResolver parentResolver) {
this.parentResolver = parentResolver;
New Page 1