SPathFilterpublic class SPathFilter extends XMLFilterImpl Filters a SAX stream based on a single supplied SPath
expression. |
Fields Summary |
---|
protected List | stepsThe steps in the SPath expression we use for filtering. | private int | depth | private Stack | acceptedDepths | private int | excludedDepth | private static final boolean | DEBUG |
Constructors Summary |
---|
public SPathFilter(Path path)Constructs a new SPathFilter, given a Path.
//*********************************************************************
// Main method (for testing)
/*
public static void main(String args[])
throws ParseException, IOException, SAXException {
// temporary...
System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
// retrieve and parse the expression
String expr = args[0];
SPathParser s = new SPathParser(expr);
Path p = s.expression();
// construct the appropriate SAX chain
// (reader -> us -> serializer)
XMLReader r = XMLReaderFactory.createXMLReader();
XMLFilter f1 = new SPathFilter(p);
XMLFilter f2 = new XMLFilterImpl();
f1.setParent(r);
f2.setParent(f1);
Serializer sz = SerializerFactory.getSerializer
(OutputProperties.getDefaultMethodProperties("xml"));
sz.setOutputStream(System.out);
f2.setContentHandler(sz.asContentHandler());
// go!
f2.parse(new InputSource(System.in));
System.out.println();
}
*/
//*********************************************************************
// Constructor and initialization methods
init();
this.steps = path.getSteps();
|
Methods Summary |
---|
public void | characters(char[] ch, int start, int length)Filter for characters().
if (isAccepted())
getContentHandler().characters(ch, start, length);
| public void | endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)Filter for endElement().
// reduce the depth
depth--;
if (isExcluded()) {
// determine if exclusion ends with us
if (excludedDepth == depth)
excludedDepth = -1;
// either way, we have been excluded, so pass nothing through
return;
}
// if we're excepted (for now), include ourselves...
if (isAccepted())
getContentHandler().endElement(uri, localName, qName);
if (DEBUG) {
System.err.println("*** Closing tag: " + localName);
System.err.println("*** acceptedDepths.size(): " + acceptedDepths.size());
System.err.println("*** last accepted depth: " + ((Integer)acceptedDepths.peek()).intValue());
System.err.println("*** depth: " + depth);
}
// now, back off if we correspond to a "successful" start tag
if (acceptedDepths.size() > 0 &&
(((Integer)acceptedDepths.peek()).intValue()) == depth)
acceptedDepths.pop();
| public void | endPrefixMapping(java.lang.String prefix)Filter for endPrefixMapping().
if (isAccepted())
getContentHandler().endPrefixMapping(prefix);
| public void | ignorableWhitespace(char[] ch, int start, int length)Filter for ignoreableWhitespace().
if (isAccepted())
getContentHandler().ignorableWhitespace(ch, start, length);
| private void | init()Initializes state used for filtering.
depth = 0;
excludedDepth = -1;
acceptedDepths = new Stack();
| private boolean | isAccepted()Returns true if events should be passed through, false otherwise.
return (acceptedDepths.size() >= steps.size());
| private boolean | isExcluded()Returns true if events should be blocked, false otherwise.
return (excludedDepth != -1);
| public static boolean | nodeMatchesStep(Step s, java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes a)
// if the name doesn't match, then we've got a loser
if (!s.isMatchingName(uri, localName))
return false;
// it's still in the game; check the predicates
List l = s.getPredicates();
for (int i = 0; l != null && i < l.size(); i++) {
Predicate p = (Predicate) l.get(i);
if (!(p instanceof AttributePredicate))
throw new UnsupportedOperationException
("only attribute predicates are supported by filter");
if (!((AttributePredicate) p).isMatchingAttribute(a))
return false; // all predicates must match
}
// it's survived
return true;
| public void | processingInstruction(java.lang.String target, java.lang.String data)Filter for processingInstruction().
if (isAccepted())
getContentHandler().processingInstruction(target, data);
| public void | skippedEntity(java.lang.String name)Filter for skippedEntity().
if (isAccepted())
getContentHandler().skippedEntity(name);
| public void | startDocument()Resets state.
init();
| public void | startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes a)Filter for startElement().
// always update the depth
depth++;
// if we're in an accepted section, simply pass through
if (isAccepted()) {
getContentHandler().startElement(uri, localName, qName, a);
return;
}
// likewise, if we're excluded, then simply block and return
if (isExcluded())
return;
// now, not accepted or excluded, let's see if we've got a match.
// we need to get the appropriate step based on the number of
// steps we've previously accepted
Step currentStep = (Step) steps.get(acceptedDepths.size());
if (nodeMatchesStep(currentStep, uri, localName, qName, a)) {
if (DEBUG)
System.err.println("*** Progressive match (" + acceptedDepths.size() + "): " + localName);
// new match (progressive)
acceptedDepths.push(Integer.valueOf(depth - 1));
// is it enough? give acceptance another chance...
if (isAccepted())
getContentHandler().startElement(uri, localName, qName, a);
} else if (!currentStep.isDepthUnlimited()) {
// if the step was preceded by '/' instead of '//', then
// we can't have a match at this node or beneath it
excludedDepth = depth - 1;
}
// nothing left to check; no reason to include node
return;
| public void | startPrefixMapping(java.lang.String prefix, java.lang.String uri)Filter for startPrefixMapping().
if (isAccepted())
getContentHandler().startPrefixMapping(prefix, uri);
|
|