1 package com.icl.saxon.style; 2 import com.icl.saxon.Context; 3 import com.icl.saxon.PreparedStyleSheet; 4 import com.icl.saxon.om.Name; 5 import com.icl.saxon.om.NamePool; 6 import com.icl.saxon.om.Namespace; 7 import com.icl.saxon.tree.TreeBuilder; 8 import com.icl.saxon.tree.DocumentImpl; 9 import com.icl.saxon.expr.Expression; 10 import com.icl.saxon.expr.StringValue; 11 import com.icl.saxon.output.Outputter; 12 import javax.xml.transform.TransformerException ; 13 import javax.xml.transform.TransformerConfigurationException ; 14 import org.xml.sax.helpers.AttributesImpl ; 15 16 17 22 23 public class LiteralResultElement extends StyleElement { 24 25 private int resultNameCode; 26 private int[] attributeNames; 27 private Expression[] attributeValues; 28 private boolean[] attributeChecked; 29 private int numberOfAttributes; 30 private boolean toplevel; 31 private int[] namespaceCodes; 32 33 34 38 39 public boolean mayContainTemplateBody() { 40 return true; 41 } 42 43 46 47 public void prepareAttributes() throws TransformerConfigurationException { 48 } 52 53 56 57 public void validate() throws TransformerConfigurationException { 58 59 toplevel = (getParentNode() instanceof XSLStyleSheet); 60 61 StandardNames sn = getStandardNames(); 62 resultNameCode = getNameCode(); 63 64 NamePool namePool = getNamePool(); 65 short elementURICode = namePool.getURICode(resultNameCode); 66 67 if (toplevel) { 68 71 if (elementURICode == 0) { 72 compileError("Top level elements must have a non-null namespace URI"); 73 } 74 } else { 75 76 78 84 91 boolean optimizeNS = false; 92 if ((getParent() instanceof LiteralResultElement) && 93 (namespaceList==null || namespaceList.length==0) && 94 ( elementURICode == 95 namePool.getURICode(getParent().getFingerprint())) 96 ) { 97 optimizeNS = true; 98 } 99 if (optimizeNS) { 100 for (int a=0; a<attributeList.getLength(); a++ ) { 101 if (((attributeList.getNameCode(a)>>20)&0xff) != 0) { optimizeNS = false; 103 break; 104 } 105 } 106 } 107 108 if (optimizeNS) { 109 namespaceCodes = new int[0]; 110 } else { 111 namespaceCodes = getNamespaceCodes(); 112 } 113 114 116 XSLStyleSheet sheet = getPrincipalStyleSheet(); 117 118 if (sheet.hasNamespaceAliases()) { 119 for (int i=0; i<namespaceCodes.length; i++) { 120 short scode = (short)(namespaceCodes[i]&0xffff); 122 short rcode = sheet.getNamespaceAlias(scode); 123 if (scode!=rcode) { 124 int prefixCode = namespaceCodes[i] & 0xffff0000; 126 namespaceCodes[i] = prefixCode | rcode; 127 } 129 } 130 131 133 short ercode = sheet.getNamespaceAlias(elementURICode); 134 135 if (ercode!=elementURICode) { 136 elementURICode = ercode; 137 resultNameCode = namePool.allocate(getPrefix(), ercode, getLocalName()); 138 } 139 } 140 141 143 int num = attributeList.getLength(); 144 attributeNames = new int[num]; 145 attributeValues = new Expression[num]; 146 attributeChecked = new boolean[num]; 147 short[] attributeURIs = new short[num]; 148 numberOfAttributes = 0; 149 150 for (int i=0; i<num; i++) { 151 152 int anameCode = attributeList.getNameCode(i); 153 int alias = anameCode; 154 int fp = anameCode & 0xfffff; 155 short attURIcode = namePool.getURICode(anameCode); 156 157 if (fp == sn.XSL_USE_ATTRIBUTE_SETS) { 158 findAttributeSets(attributeList.getValue(i)); 159 } else if (fp == sn.XSL_EXTENSION_ELEMENT_PREFIXES) { 160 } else if (fp == sn.XSL_EXCLUDE_RESULT_PREFIXES) { 162 } else if (fp == sn.XSL_VERSION) { 164 } else { 166 167 if (attURIcode==Namespace.XSLT_CODE) { 168 compileError("Unknown XSL attribute " + namePool.getDisplayName(anameCode)); 169 } 170 if (attURIcode!=0) { short attAlias = sheet.getNamespaceAlias(attURIcode); 172 if (attAlias != attURIcode) { 173 String qName = namePool.getDisplayName(anameCode); 174 String newPrefix = Name.getPrefix(qName); 175 String newLocalName = Name.getLocalName(qName); 176 String newURI = namePool.getURIFromNamespaceCode(attAlias); 178 alias = namePool.allocate(newPrefix, newURI, newLocalName); 179 attURIcode = attAlias; 181 } 182 } 183 184 attributeNames[numberOfAttributes] = alias; 185 attributeURIs[numberOfAttributes] = attURIcode; 186 Expression exp = makeAttributeValueTemplate(attributeList.getValue(i)); 187 attributeValues[numberOfAttributes] = exp; 188 189 194 attributeChecked[numberOfAttributes] = false; 195 boolean special = false; 196 if (exp instanceof StringValue) { 197 String val = ((StringValue)exp).asString(); 198 for (int k=0; k<val.length(); k++) { 199 char c = val.charAt(k); 200 if ((int)c<33 || (int)c>126 || 201 c=='<' || c=='>' || c=='&' || c=='\"') { 202 special = true; 203 break; 204 } 205 } 206 attributeChecked[numberOfAttributes] = !special; 207 } 208 numberOfAttributes++; 209 } 210 } 211 212 215 for (int n=0; n<namespaceCodes.length; n++) { 216 short uricode = (short)(namespaceCodes[n] & 0xffff); 217 if (isExcludedNamespace(uricode)) { 218 219 boolean exclude = true; 220 221 223 if (uricode==elementURICode) { 224 exclude = false; 225 } 226 227 229 for (int a=0; a<numberOfAttributes; a++) { 230 if (uricode==attributeURIs[a]) { 231 exclude = false; 232 break; 233 } 234 } 235 236 238 if (exclude) { 239 namespaceCodes[n] = -1; 240 } 241 } 242 } 243 244 } 245 } 246 247 protected void validateChildren () throws TransformerConfigurationException { 248 if (!toplevel) { 250 super.validateChildren(); 251 } 252 } 253 254 257 258 public void process(Context context) throws TransformerException 259 { 260 if (toplevel) return; 262 263 Outputter o = context.getOutputter(); 265 o.writeStartTag(resultNameCode); 266 267 269 for (int i=0; i<namespaceCodes.length; i++) { 270 if (namespaceCodes[i]!=-1) { 271 o.writeNamespaceDeclaration(namespaceCodes[i]); 272 } 273 } 274 275 277 processAttributeSets(context); 278 279 281 for (int i=0; i<numberOfAttributes; i++) { 282 int attname = attributeNames[i]; 283 String attval = attributeValues[i].evaluateAsString(context); 284 o.writeAttribute(attname, attval, attributeChecked[i]); 285 } 286 287 289 processChildren(context); 290 291 293 o.writeEndTag(resultNameCode); 294 295 } 296 297 301 302 public DocumentImpl makeStyleSheet(PreparedStyleSheet pss) throws TransformerConfigurationException { 303 304 307 NamePool pool = getNamePool(); 308 StandardNames sn = getStandardNames(); 309 String xslPrefix = getPrefixForURI(Namespace.XSLT); 310 if (xslPrefix==null) { 311 String message; 312 if (getLocalName().equals("stylesheet") || getLocalName().equals("transform")) { 313 if (getPrefixForURI(Namespace.MICROSOFT_XSL)!=null) { 314 message = "Saxon is not able to process Microsoft's WD-xsl dialect"; 315 } else { 316 message = "Namespace for stylesheet element should be " + Namespace.XSLT; 317 } 318 } else { 319 message = "The supplied file does not appear to be a stylesheet"; 320 } 321 TransformerConfigurationException err = 322 new TransformerConfigurationException (message); 323 try {pss.reportError(err);} catch(TransformerException err2) {} 324 throw err; 325 326 } 327 328 331 String version = getAttributeValue(sn.XSL_VERSION); 332 if (version==null) { 333 TransformerConfigurationException err = 334 new TransformerConfigurationException ( 335 "Literal Result Element As Stylesheet: xsl:version attribute is missing"); 336 try {pss.reportError(err);} catch(TransformerException err2) {} 337 throw err; 338 } 339 340 try { 341 TreeBuilder builder = new TreeBuilder(); 342 builder.setDocumentLocator(null); 343 builder.setNamePool(pool); 344 builder.setNodeFactory(((DocumentImpl)getParentNode()).getNodeFactory()); 345 builder.setSystemId(this.getSystemId()); 346 347 builder.startDocument(); 348 AttributesImpl atts = new AttributesImpl (); 349 atts.addAttribute("", "version", "version", "CDATA", version); 350 int[] namespaces = new int[1]; 351 namespaces[0] = pool.getNamespaceCode("xsl", Namespace.XSLT); 352 int st = pool.allocate("xsl", Namespace.XSLT, "stylesheet"); 353 builder.startElement(st, atts, namespaces, 1); 354 355 int te = pool.allocate("xsl", Namespace.XSLT, "template"); 356 atts.clear(); 357 atts.addAttribute("", "match", "match", "CDATA", "/"); 358 builder.startElement(te, atts, namespaces, 0); 359 360 builder.graftElement(this); 361 362 builder.endElement(te); 363 builder.endElement(st); 364 builder.endDocument(); 365 366 return (DocumentImpl)builder.getCurrentDocument(); 367 } catch (TransformerException err) { 368 throw new TransformerConfigurationException (err); 369 } 370 371 } 372 373 374 } 375 | Popular Tags |