1 21 22 package nu.xom.xslt; 23 24 import java.util.Stack ; 25 26 import nu.xom.Attribute; 27 import nu.xom.Element; 28 import nu.xom.NamespaceConflictException; 29 import nu.xom.Node; 30 import nu.xom.NodeFactory; 31 import nu.xom.Nodes; 32 import nu.xom.ParentNode; 33 import nu.xom.XMLException; 34 35 import org.xml.sax.Attributes ; 36 import org.xml.sax.ContentHandler ; 37 import org.xml.sax.Locator ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.ext.LexicalHandler ; 40 import org.xml.sax.helpers.AttributesImpl ; 41 42 56 class XSLTHandler 57 implements ContentHandler , LexicalHandler { 58 59 private Nodes result; 60 private Stack parents; 61 private NodeFactory factory; 62 private StringBuffer buffer; 63 64 65 XSLTHandler(NodeFactory factory) { 66 this.factory = factory; 67 result = new Nodes(); 68 parents = new Stack (); 69 buffer = new StringBuffer (); 70 } 71 72 73 Nodes getResult() { 74 flushText(); return result; 76 } 77 78 79 public void setDocumentLocator(Locator locator) {} 80 public void startDocument() {} 81 public void endDocument() {} 82 83 private Element current; 84 85 public void startElement(String namespaceURI, String localName, 86 String qualifiedName, Attributes attributes) { 87 88 flushText(); 89 90 for (int i = 0; i < attributes.getLength(); i++) { 92 namespaceDeclarations.addAttribute( 93 attributes.getURI(i), 94 attributes.getLocalName(i), 95 attributes.getQName(i), 96 attributes.getType(i), 97 attributes.getValue(i) 98 ); 99 } 100 attributes = namespaceDeclarations; 101 102 Element element 103 = factory.startMakingElement(qualifiedName, namespaceURI); 104 105 if (parents.isEmpty()) { 106 current = element; 108 } 109 else { 110 ParentNode parent = (ParentNode) parents.peek(); 111 parent.appendChild(element); 112 } 113 parents.push(element); 114 115 for (int i = 0; i < attributes.getLength(); i++) { 117 String attributeName = attributes.getQName(i); 118 if (attributeName.equals("xmlns") 120 || attributeName.startsWith("xmlns:")) { 121 continue; 122 } 123 String namespace = attributes.getURI(i); 124 String value = attributes.getValue(i); 125 126 Nodes nodes = factory.makeAttribute( 127 attributeName, 128 namespace, 129 value, 130 Attribute.Type.UNDECLARED 131 ); 132 for (int j=0; j < nodes.size(); j++) { 133 Node node = nodes.get(j); 134 if (node instanceof Attribute) { 135 Attribute attribute = (Attribute) node; 136 while (true) { 137 try { 138 element.addAttribute(attribute); 139 break; 140 } 141 catch (NamespaceConflictException ex) { 142 attribute.setNamespace( 148 "p"+attribute.getNamespacePrefix(), 149 attribute.getNamespaceURI() 150 ); 151 } 152 } 153 } 154 else { 155 element.appendChild(node); 156 } 157 } 158 } 159 160 for (int i = 0; i < attributes.getLength(); i++) { 162 String qName = attributes.getQName(i); 163 if (qName.startsWith("xmlns:")) { 164 String namespaceName = attributes.getValue(i); 165 String namespacePrefix = qName.substring(6); 166 String currentValue 167 = element.getNamespaceURI(namespacePrefix); 168 if (!namespaceName.equals(currentValue)) { 169 try { 170 element.addNamespaceDeclaration( 171 namespacePrefix, namespaceName); 172 } 173 catch (NamespaceConflictException ex) { 174 } 180 } 181 } 182 else if (qName.equals("xmlns")) { 183 String namespaceName = attributes.getValue(i); 184 if (namespaceName == null) { namespaceName = ""; 186 } 187 String namespacePrefix = ""; 188 String currentValue 189 = element.getNamespaceURI(namespacePrefix); 190 if (!namespaceName.equals(currentValue)) { 191 try { 192 element.addNamespaceDeclaration(namespacePrefix, 193 namespaceName); 194 } 195 catch (NamespaceConflictException ex) { 196 if ("http://www.w3.org/XML/1998/namespace".equals(namespaceName) 202 && "".equals(namespacePrefix)) { 203 element.addNamespaceDeclaration("", ""); 204 } 205 } 206 } 207 } 208 } 209 210 namespaceDeclarations = new AttributesImpl (); 212 213 } 214 215 216 public void endElement(String namespaceURI, String localName, 217 String qualifiedName) { 218 219 flushText(); 220 Element element = (Element) parents.pop(); 221 if (parents.isEmpty()) { 222 Nodes nodes = factory.finishMakingElement(current); 223 for (int i = 0; i < nodes.size(); i++) { 224 result.append(nodes.get(i)); 225 } 226 current = null; 227 } 228 else { 229 Nodes nodes = factory.finishMakingElement(element); 230 ParentNode parent = element.getParent(); 231 element.detach(); 232 for (int i = 0; i < nodes.size(); i++) { 233 Node node = nodes.get(i); 234 if (node instanceof Attribute) { 235 ((Element) parent).addAttribute((Attribute) node); 236 } 237 else { 238 parent.appendChild(node); 239 } 240 } 241 } 242 243 } 244 245 246 public void characters(char[] text, int start, int length) { 247 buffer.append(text, start, length); 248 } 249 250 251 private void flushText() { 253 if (buffer.length() > 0) { 254 Nodes text = factory.makeText(buffer.toString()); 255 addToResultTree(text); 256 buffer = new StringBuffer (); 257 } 258 } 259 260 261 public void ignorableWhitespace(char[] text, int start, int length) { 262 characters(text, start, length); 263 } 264 265 266 public void processingInstruction(String target, String data) 267 throws SAXException { 268 269 if ("saxon:warning".equals(target)) { 272 throw new SAXException ("continue"); 273 } 274 else if ("javax.xml.transform.disable-output-escaping".equals(target) 275 || "javax.xml.transform.enable-output-escaping".equals(target)) { 276 return; 278 } 279 280 flushText(); 281 int position = data.indexOf("?>"); 284 while (position != -1) { 285 data = data.substring(0, position) + "? >" + data.substring(position+2); 286 position = data.indexOf("?>"); 287 } 288 Nodes nodes = factory.makeProcessingInstruction(target, data); 289 addToResultTree(nodes); 290 291 } 292 293 294 private void addToResultTree(Nodes nodes) { 295 296 if (parents.isEmpty()) { 297 for (int i = 0; i < nodes.size(); i++) { 298 result.append(nodes.get(i)); 299 } 300 } 301 else { 302 ParentNode parent = (ParentNode) parents.peek(); 303 for (int i = 0; i < nodes.size(); i++) { 304 Node node = nodes.get(i); 305 if (node instanceof Attribute) { 306 ((Element) parent).addAttribute((Attribute) node); 307 } 308 else { 309 parent.appendChild(node); 310 } 311 } 312 } 313 314 } 315 316 317 public void endPrefixMapping(String prefix) {} 318 319 320 private AttributesImpl namespaceDeclarations = new AttributesImpl (); 321 322 public void startPrefixMapping(String prefix, String uri) { 323 324 if ("".equals(prefix)) { 325 namespaceDeclarations.addAttribute("", "xmlns", "xmlns", "CDATA", uri); 326 } 327 else { 328 namespaceDeclarations.addAttribute("", "xmlns:" + prefix, "xmlns:" + prefix, "CDATA", uri); 329 } 330 331 } 332 333 334 public void skippedEntity(String name) { 335 flushText(); 336 throw new XMLException("Could not resolve entity " + name); 337 } 338 339 340 public void startCDATA() {} 342 public void endCDATA() {} 343 public void startDTD(String name, String publicID, String systemID) {} 344 public void endDTD() {} 345 public void startEntity(String name) {} 346 public void endEntity(String name) {} 347 348 349 public void comment(char[] text, int start, int length) { 350 351 flushText(); 352 353 String data = new String (text, start, length); 354 int position = data.indexOf("--"); 357 while (position != -1) { 358 data = data.substring(0, position) + "- -" + data.substring(position+2); 359 position = data.indexOf("--"); 360 } 361 if (data.endsWith("-")) data += ' '; 362 363 addToResultTree(factory.makeComment(data)); 364 365 } 366 367 368 } | Popular Tags |