1 16 17 package org.apache.taglibs.standard.extra.spath; 18 19 import java.io.IOException ; 20 import java.util.List ; 21 import java.util.Stack ; 22 23 import org.apache.xalan.serialize.Serializer; 24 import org.apache.xalan.serialize.SerializerFactory; 25 import org.apache.xalan.templates.OutputProperties; 26 import org.xml.sax.Attributes ; 27 import org.xml.sax.InputSource ; 28 import org.xml.sax.SAXException ; 29 import org.xml.sax.XMLFilter ; 30 import org.xml.sax.XMLReader ; 31 import org.xml.sax.helpers.XMLFilterImpl ; 32 import org.xml.sax.helpers.XMLReaderFactory ; 33 34 40 public class SPathFilter extends XMLFilterImpl { 41 42 45 46 protected List steps; 47 48 51 private int depth; private Stack acceptedDepths; private int excludedDepth; 55 private static final boolean DEBUG = false; 56 57 60 61 public static void main(String args[]) 62 throws ParseException, IOException , SAXException { 63 System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); 65 66 String expr = args[0]; 68 SPathParser s = new SPathParser(expr); 69 Path p = s.expression(); 70 71 XMLReader r = XMLReaderFactory.createXMLReader(); 74 XMLFilter f1 = new SPathFilter(p); 75 XMLFilter f2 = new XMLFilterImpl (); 76 f1.setParent(r); 77 f2.setParent(f1); 78 Serializer sz = SerializerFactory.getSerializer 79 (OutputProperties.getDefaultMethodProperties("xml")); 80 sz.setOutputStream(System.out); 81 f2.setContentHandler(sz.asContentHandler()); 82 83 f2.parse(new InputSource (System.in)); 85 System.out.println(); 86 } 87 88 91 92 public SPathFilter(Path path) { 93 init(); 94 this.steps = path.getSteps(); 95 } 96 97 98 private void init() { 99 depth = 0; 100 excludedDepth = -1; 101 acceptedDepths = new Stack (); 102 } 103 104 107 110 111 public void startElement(String uri, 112 String localName, 113 String qName, 114 Attributes a) throws SAXException { 115 depth++; 117 118 if (isAccepted()) { 120 getContentHandler().startElement(uri, localName, qName, a); 121 return; 122 } 123 124 if (isExcluded()) 126 return; 127 128 Step currentStep = (Step) steps.get(acceptedDepths.size()); 132 133 if (nodeMatchesStep(currentStep, uri, localName, qName, a)) { 134 if (DEBUG) 135 System.err.println("*** Progressive match (" + acceptedDepths.size() + "): " + localName); 136 acceptedDepths.push(new Integer (depth - 1)); 138 139 if (isAccepted()) 141 getContentHandler().startElement(uri, localName, qName, a); 142 } else if (!currentStep.isDepthUnlimited()) { 143 excludedDepth = depth - 1; 146 } 147 148 return; 150 } 151 152 153 public void endElement(String uri, String localName, String qName) 154 throws SAXException { 155 depth--; 157 158 if (isExcluded()) { 159 if (excludedDepth == depth) 161 excludedDepth = -1; 162 163 return; 165 } 166 167 if (isAccepted()) 169 getContentHandler().endElement(uri, localName, qName); 170 171 if (DEBUG) { 172 System.err.println("*** Closing tag: " + localName); 173 System.err.println("*** acceptedDepths.size(): " + acceptedDepths.size()); 174 System.err.println("*** last accepted depth: " + ((Integer )acceptedDepths.peek()).intValue()); 175 System.err.println("*** depth: " + depth); 176 } 177 178 if (acceptedDepths.size() > 0 && 180 (((Integer )acceptedDepths.peek()).intValue()) == depth) 181 acceptedDepths.pop(); 182 } 183 184 189 190 public void ignorableWhitespace(char[] ch, int start, int length) 191 throws SAXException { 192 if (isAccepted()) 193 getContentHandler().ignorableWhitespace(ch, start, length); 194 } 195 196 197 public void characters(char[] ch, int start, int length) 198 throws SAXException { 199 if (isAccepted()) 200 getContentHandler().characters(ch, start, length); 201 } 202 203 204 public void startPrefixMapping(String prefix, String uri) 205 throws SAXException { 206 if (isAccepted()) 207 getContentHandler().startPrefixMapping(prefix, uri); 208 } 209 210 211 public void endPrefixMapping(String prefix) 212 throws SAXException { 213 if (isAccepted()) 214 getContentHandler().endPrefixMapping(prefix); 215 } 216 217 218 public void processingInstruction(String target, String data) 219 throws SAXException { 220 if (isAccepted()) 221 getContentHandler().processingInstruction(target, data); 222 } 223 224 225 public void skippedEntity(String name) throws SAXException { 226 if (isAccepted()) 227 getContentHandler().skippedEntity(name); 228 } 229 230 232 public void startDocument() { 233 init(); 234 } 235 236 239 public static boolean nodeMatchesStep(Step s, 240 String uri, 241 String localName, 242 String qName, 243 Attributes a) { 244 if (!s.isMatchingName(uri, localName)) 246 return false; 247 248 List l = s.getPredicates(); 250 for (int i = 0; l != null && i < l.size(); i++) { 251 Predicate p = (Predicate) l.get(i); 252 if (!(p instanceof AttributePredicate)) 253 throw new UnsupportedOperationException 254 ("only attribute predicates are supported by filter"); 255 if (!((AttributePredicate) p).isMatchingAttribute(a)) 256 return false; } 258 259 return true; 261 } 262 263 264 private boolean isAccepted() { 265 return (acceptedDepths.size() >= steps.size()); 266 } 267 268 269 private boolean isExcluded() { 270 return (excludedDepth != -1); 271 } 272 } 273 | Popular Tags |