1 package net.sf.saxon.event; 2 import net.sf.saxon.Controller; 3 import net.sf.saxon.expr.XPathContext; 4 import net.sf.saxon.om.NodeInfo; 5 import net.sf.saxon.om.Orphan; 6 import net.sf.saxon.style.StandardNames; 7 import net.sf.saxon.trans.Mode; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.ComplexType; 10 import net.sf.saxon.type.SchemaType; 11 import net.sf.saxon.type.Type; 12 import net.sf.saxon.value.Whitespace; 13 14 19 20 21 public class Stripper extends ProxyReceiver { 22 23 private boolean preserveAll; private boolean stripAll; 26 31 34 private byte[] stripStack = new byte[100]; 35 private int top = 0; 36 37 40 private Mode stripperMode; 41 42 private Orphan element; 44 45 private XPathContext context; 48 49 52 53 protected Stripper() {} 54 55 60 61 public Stripper(Mode stripperRules) { 62 stripperMode = stripperRules; 63 preserveAll = (stripperRules==null); 64 stripAll = false; 65 } 66 67 70 71 public Stripper getAnother() { 72 Stripper clone = new Stripper(stripperMode); 73 clone.setPipelineConfiguration(getPipelineConfiguration()); 74 clone.stripAll = stripAll; 75 clone.preserveAll = preserveAll; 76 return clone; 77 } 78 79 80 83 84 public void setStripAll() { 85 preserveAll = false; 86 stripAll = true; 87 } 88 89 93 94 public boolean getStripAll() { 95 return stripAll; 96 } 97 98 public void setPipelineConfiguration(PipelineConfiguration pipe) { 99 super.setPipelineConfiguration(pipe); 100 Controller controller = pipe.getController(); 101 if (controller != null) { 102 context = controller.newXPathContext(); 103 } 104 element = new Orphan(pipe.getConfiguration()); 105 element.setNodeKind(Type.ELEMENT); 106 } 107 108 116 117 118 119 public byte isSpacePreserving(int nameCode) { 120 try { 121 if (preserveAll) return ALWAYS_PRESERVE; 122 if (stripAll) return STRIP_DEFAULT; 123 element.setNameCode(nameCode); 124 Object rule = stripperMode.getRule(element, context); 125 if (rule==null) return ALWAYS_PRESERVE; 126 return (((Boolean )rule).booleanValue() ? ALWAYS_PRESERVE : STRIP_DEFAULT); 127 } catch (XPathException err) { 128 return ALWAYS_PRESERVE; 129 } 130 } 131 132 public static final byte ALWAYS_PRESERVE = 0x01; public static final byte ALWAYS_STRIP = 0x02; public static final byte STRIP_DEFAULT = 0x00; public static final byte PRESERVE_PARENT = 0x04; public static final byte CANNOT_STRIP = 0x08; 138 148 149 public byte isSpacePreserving(NodeInfo element) { 150 try { 151 if (preserveAll) return ALWAYS_PRESERVE; 152 if (stripAll) return STRIP_DEFAULT; 153 Object rule = stripperMode.getRule(element, context); 154 if (rule==null) return ALWAYS_PRESERVE; 155 return (((Boolean )rule).booleanValue() ? ALWAYS_PRESERVE : STRIP_DEFAULT); 156 } catch (XPathException err) { 157 return ALWAYS_PRESERVE; 158 } 159 } 160 161 162 165 166 public void open () throws XPathException { 167 top = 0; 169 stripStack[top] = ALWAYS_PRESERVE; super.open(); 171 } 172 173 public void startElement (int nameCode, int typeCode, int locationId, int properties) throws XPathException 174 { 175 super.startElement(nameCode, typeCode, locationId, properties); 177 178 byte preserveParent = stripStack[top]; 179 byte preserve = (byte)(preserveParent & PRESERVE_PARENT); 180 181 byte elementStrip = isSpacePreserving(nameCode); 182 if (elementStrip == ALWAYS_PRESERVE) { 183 preserve |= ALWAYS_PRESERVE; 184 } else if (elementStrip == ALWAYS_STRIP) { 185 preserve |= ALWAYS_STRIP; 186 } 187 if (preserve == 0 && typeCode != -1 && typeCode != StandardNames.XDT_UNTYPED) { 188 SchemaType type = getConfiguration().getSchemaType(typeCode); 190 if (type.isSimpleType() || ((ComplexType)type).isSimpleContent()) { 191 preserve |= CANNOT_STRIP; 192 } 193 } 194 195 197 top++; 198 if (top >= stripStack.length) { 199 byte[] newStack = new byte[top*2]; 200 System.arraycopy(stripStack, 0, newStack, 0, top); 201 stripStack = newStack; 202 } 203 stripStack[top] = preserve; 204 } 205 206 public void attribute(int nameCode, int typeCode, CharSequence value, int locationId, int properties) 207 throws XPathException { 208 209 211 if ((nameCode & 0xfffff) == StandardNames.XML_SPACE) { 212 if (value.toString().equals("preserve")) { 213 stripStack[top] |= PRESERVE_PARENT; 214 } else { 215 stripStack[top] &= ~PRESERVE_PARENT; 216 } 217 } 218 super.attribute(nameCode, typeCode, value, locationId, properties); 219 } 220 221 224 225 public void endElement () throws XPathException 226 { 227 super.endElement(); 228 top--; 229 } 230 231 234 235 public void characters (CharSequence chars, int locationId, int properties) throws XPathException 236 { 237 239 if (chars.length() > 0) { 240 if ((((stripStack[top] & (ALWAYS_PRESERVE | PRESERVE_PARENT | CANNOT_STRIP)) != 0) && 241 (stripStack[top] & ALWAYS_STRIP) == 0) 242 || !Whitespace.isWhite(chars)) { 243 super.characters(chars, locationId, properties); 244 } 245 } 246 } 247 248 249 } 250 251 | Popular Tags |