1 package net.sf.saxon.style; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.PreparedStylesheet; 4 import net.sf.saxon.expr.Expression; 5 import net.sf.saxon.expr.ExpressionTool; 6 import net.sf.saxon.expr.ComputedExpression; 7 import net.sf.saxon.instruct.*; 8 import net.sf.saxon.om.*; 9 import net.sf.saxon.trace.Location; 10 import net.sf.saxon.trans.SaxonErrorCode; 11 import net.sf.saxon.trans.StaticError; 12 import net.sf.saxon.trans.XPathException; 13 import net.sf.saxon.tree.DocumentImpl; 14 import net.sf.saxon.tree.TreeBuilder; 15 import net.sf.saxon.type.SchemaType; 16 import net.sf.saxon.value.EmptySequence; 17 18 import javax.xml.transform.TransformerException ; 19 20 21 26 27 public class LiteralResultElement extends StyleElement { 28 29 private int resultNameCode; 30 private int[] attributeNames; 31 private Expression[] attributeValues; 32 private int numberOfAttributes; 34 private boolean toplevel; 35 private int[] namespaceCodes; 36 private AttributeSet[] attributeSets; 37 private SchemaType schemaType = null; 38 private int validation = Validation.STRIP; 39 private boolean inheritNamespaces = true; 40 41 45 46 public boolean mayContainSequenceConstructor() { 47 return true; 48 } 49 50 53 54 public boolean isInstruction() { 55 return true; 56 } 57 58 61 62 public void prepareAttributes() throws XPathException { 63 64 68 int num = attributeList.getLength(); 69 70 if (num == 0) { 71 numberOfAttributes = 0; 72 } else { 73 NamePool namePool = getNamePool(); 74 attributeNames = new int[num]; 75 attributeValues = new Expression[num]; 76 numberOfAttributes = 0; 78 79 for (int i=0; i<num; i++) { 80 81 int anameCode = attributeList.getNameCode(i); 82 short attURIcode = namePool.getURICode(anameCode); 83 84 if (attURIcode==NamespaceConstant.XSLT_CODE) { 85 int fp = anameCode & 0xfffff; 86 87 if (fp == StandardNames.XSL_USE_ATTRIBUTE_SETS) { 88 } else if (fp == StandardNames.XSL_DEFAULT_COLLATION) { 90 } else if (fp == StandardNames.XSL_EXTENSION_ELEMENT_PREFIXES) { 92 } else if (fp == StandardNames.XSL_EXCLUDE_RESULT_PREFIXES) { 94 } else if (fp == StandardNames.XSL_VERSION) { 96 } else if (fp == StandardNames.XSL_XPATH_DEFAULT_NAMESPACE) { 98 } else if (fp == StandardNames.XSL_TYPE) { 100 } else if (fp == StandardNames.XSL_USE_WHEN) { 102 } else if (fp == StandardNames.XSL_VALIDATION) { 104 } else if (fp == StandardNames.XSL_INHERIT_NAMESPACES) { 106 String inheritAtt = attributeList.getValue(i); 107 if (inheritAtt.equals("yes")) { 108 inheritNamespaces = true; 109 } else if (inheritAtt.equals("no")) { 110 inheritNamespaces = false; 111 } else { 112 compileError("The xsl:inherit-namespaces attribute has permitted values (yes, no)", "XTSE0020"); 113 } 114 } else { 115 compileError("Unknown XSL attribute " + namePool.getDisplayName(anameCode), "XTSE0010"); 116 } 117 } else { 118 attributeNames[numberOfAttributes] = anameCode; 119 Expression exp = makeAttributeValueTemplate(attributeList.getValue(i)); 120 attributeValues[numberOfAttributes] = exp; 121 122 127 numberOfAttributes++; 142 } 143 } 144 145 148 if (numberOfAttributes < attributeNames.length) { 149 150 int[] attributeNames2 = new int[numberOfAttributes]; 151 System.arraycopy(attributeNames, 0, attributeNames2, 0, numberOfAttributes); 152 attributeNames = attributeNames2; 153 154 Expression[] attributeValues2 = new Expression[numberOfAttributes]; 155 System.arraycopy(attributeValues, 0, attributeValues2, 0, numberOfAttributes); 156 attributeValues = attributeValues2; 157 158 } 162 } 163 } 164 165 168 169 public void validate() throws XPathException { 170 171 toplevel = (getParent() instanceof XSLStylesheet); 172 173 resultNameCode = getNameCode(); 174 175 NamePool namePool = getNamePool(); 176 short elementURICode = namePool.getURICode(resultNameCode); 177 178 if (toplevel) { 179 182 if (elementURICode == 0) { 183 compileError("Top level elements must have a non-null namespace URI", "XTSE0010"); 184 } 185 } else { 186 187 189 195 203 boolean optimizeNS = false; 204 NodeInfo parent = getParent(); 205 if ((parent instanceof LiteralResultElement) && 206 ((LiteralResultElement)parent).inheritNamespaces && 207 (namespaceList==null || namespaceList.length==0) && 208 ( elementURICode == namePool.getURICode(getParent().getFingerprint()))) { 209 optimizeNS = true; 210 } 211 if (optimizeNS) { 212 for (int a=0; a<attributeList.getLength(); a++ ) { 213 if (((attributeList.getNameCode(a)>>20)&0xff) != 0) { optimizeNS = false; 215 break; 216 } 217 } 218 } 219 220 if (optimizeNS) { 221 namespaceCodes = NodeInfo.EMPTY_NAMESPACE_LIST; 222 } else { 223 namespaceCodes = getInScopeNamespaceCodes(); 224 } 225 226 228 XSLStylesheet sheet = getPrincipalStylesheet(); 229 230 if (sheet.hasNamespaceAliases()) { 231 for (int i=0; i<namespaceCodes.length; i++) { 232 short scode = (short)(namespaceCodes[i]&0xffff); 234 int ncode = sheet.getNamespaceAlias(scode); 235 if (ncode != -1 && (ncode & 0xffff) != scode) { 236 namespaceCodes[i] = ncode; 239 } 240 } 241 242 244 int ercode = sheet.getNamespaceAlias(elementURICode); 245 if ((ercode & 0xffff) != elementURICode) { 246 resultNameCode = namePool.allocate(namePool.getPrefixFromNamespaceCode(ercode), 247 namePool.getURIFromNamespaceCode(ercode), 248 getLocalPart()); 249 } 250 } 251 252 254 String useAttSets = getAttributeValue(StandardNames.XSL_USE_ATTRIBUTE_SETS); 255 if (useAttSets != null) { 256 attributeSets = getAttributeSets(useAttSets, null); 257 } 258 259 String type = getAttributeValue(StandardNames.XSL_TYPE); 260 if (type != null) { 261 if (!getConfiguration().isSchemaAware(Configuration.XSLT)) { 262 compileError("The xsl:type attribute is available only with a schema-aware XSLT processor", "XTSE1660"); 263 } 264 schemaType = getSchemaType(type); 265 } 266 267 String validate = getAttributeValue(StandardNames.XSL_VALIDATION); 268 if (validate != null) { 269 validation = Validation.getCode(validate); 270 if (validation != Validation.STRIP && !getConfiguration().isSchemaAware(Configuration.XSLT)) { 271 compileError("To perform validation, a schema-aware XSLT processor is needed", "XTSE1660"); 272 } 273 if (validation == Validation.INVALID) { 274 compileError("Invalid value for xsl:validation. " + 275 "Permitted values are (strict, lax, preserve, strip)", "XTSE0020"); 276 } 277 } else { 278 validation = getContainingStylesheet().getDefaultValidation(); 279 } 280 281 284 short attributeURIs[] = new short[numberOfAttributes]; 285 if (numberOfAttributes > 0) { 286 287 for (int i=0; i<numberOfAttributes; i++) { 288 289 int anameCode = attributeNames[i]; 290 int alias = anameCode; 291 short attURIcode = namePool.getURICode(anameCode); 292 293 if (attURIcode!=0) { int newNSCode = sheet.getNamespaceAlias(attURIcode); 295 if ((newNSCode & 0xffff) != attURIcode) { 296 attURIcode = (short)(newNSCode & 0xffff); 297 alias = namePool.allocate( namePool.getPrefixFromNamespaceCode(newNSCode), 298 namePool.getURIFromNamespaceCode(newNSCode), 299 attributeList.getLocalName(i)); 300 } 301 } 302 303 attributeNames[i] = alias; 305 attributeURIs[i] = attURIcode; 306 attributeValues[i] = typeCheck(namePool.getDisplayName(alias), attributeValues[i]); 307 } 308 } 309 310 313 int numberExcluded = 0; 314 for (int n=0; n<namespaceCodes.length; n++) { 315 short uricode = (short)(namespaceCodes[n] & 0xffff); 316 if (isExcludedNamespace(uricode) && !sheet.isAliasResultNamespace(uricode)) { 317 namespaceCodes[n] = -1; 319 numberExcluded++; 320 } 321 } 322 323 326 341 int count = namespaceCodes.length - numberExcluded; 342 int[] newNamespaceCodes = new int[count]; 343 count = 0; 344 for (int i=0; i<namespaceCodes.length; i++) { 345 if (namespaceCodes[i] != -1) { 346 newNamespaceCodes[count++] = namespaceCodes[i]; 347 } 348 } 349 namespaceCodes = newNamespaceCodes; 350 } 351 } 352 353 357 358 protected void validateChildren() throws XPathException { 359 if (!toplevel) { 360 super.validateChildren(); 361 } 362 } 363 364 367 368 377 380 381 public Expression compile(Executable exec) throws XPathException { 382 if (toplevel) return null; 384 385 FixedElement inst = new FixedElement( 386 resultNameCode, 387 namespaceCodes, 388 inheritNamespaces, 389 schemaType, 390 validation); 391 392 Expression content = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true); 393 if (content instanceof ComputedExpression) { 394 ((ComputedExpression)content).setParentExpression(inst); 395 } 396 397 if (numberOfAttributes > 0) { 398 for (int i=attributeNames.length - 1; i>=0; i--) { 399 FixedAttribute att = new FixedAttribute( 400 attributeNames[i], 401 Validation.STRIP, 402 null, 403 StandardNames.XDT_UNTYPED_ATOMIC); 404 try { 405 att.setSelect(attributeValues[i]); 406 } catch (XPathException err) { 407 compileError(err); 408 } 409 att.setLocationId(allocateLocationId(getSystemId(), getLineNumber())); 410 att.setParentExpression(inst); 411 ExpressionTool.makeParentReferences(att); 412 if (content == null) { 416 content = att; 417 } else { 418 content = Block.makeBlock(att, content); 419 } 420 } 421 } 422 423 if (attributeSets != null) { 424 UseAttributeSets use = new UseAttributeSets(attributeSets); 425 if (content == null) { 426 content = use; 427 } else { 428 content = Block.makeBlock(use, content); 429 } 430 } 431 432 if (content == null) { 433 content = EmptySequence.getInstance(); 434 } 435 inst.setContentExpression(content); 436 437 ExpressionTool.makeParentReferences(inst); 438 return inst; 439 } 440 441 445 446 public DocumentImpl makeStylesheet(PreparedStylesheet pss, 447 StyleNodeFactory nodeFactory) 448 throws XPathException { 449 450 453 NamePool pool = getNamePool(); 454 String xslPrefix = getPrefixForURI(NamespaceConstant.XSLT); 455 if (xslPrefix==null) { 456 String message; 457 if (getLocalPart().equals("stylesheet") || getLocalPart().equals("transform")) { 458 if (getPrefixForURI(NamespaceConstant.MICROSOFT_XSL)!=null) { 459 message = "Saxon is not able to process Microsoft's WD-xsl dialect"; 460 } else { 461 message = "Namespace for stylesheet element should be " + NamespaceConstant.XSLT; 462 } 463 } else { 464 message = "The supplied file does not appear to be a stylesheet"; 465 } 466 StaticError err = new StaticError (message); 467 err.setLocator(this); 468 err.setErrorCode(SaxonErrorCode.SXIN0004); 469 try { 470 pss.reportError(err); 471 } catch (TransformerException err2) {} 472 throw err; 473 474 } 475 476 479 String version = getAttributeValue(StandardNames.XSL_VERSION); 480 if (version==null) { 481 StaticError err = new StaticError ( 482 "Simplified stylesheet: xsl:version attribute is missing"); 483 err.setErrorCode("XTSE0150"); 484 err.setLocator(this); 485 try { 486 pss.reportError(err); 487 } catch(TransformerException err2) {} 488 throw err; 489 } 490 491 try { 492 TreeBuilder builder = new TreeBuilder(); 493 builder.setPipelineConfiguration(pss.getConfiguration().makePipelineConfiguration()); 494 builder.setNodeFactory(nodeFactory); 495 builder.setSystemId(this.getSystemId()); 496 497 builder.open(); 498 builder.startDocument(0); 499 500 int st = StandardNames.XSL_STYLESHEET; 501 builder.startElement(st, StandardNames.XDT_UNTYPED, 0, 0); 502 builder.namespace(NamespaceConstant.XSLT_CODE, 0); 503 builder.attribute(pool.allocate("", "", "version"), StandardNames.XDT_UNTYPED_ATOMIC, version, 0, 0); 504 builder.startContent(); 505 506 int te = StandardNames.XSL_TEMPLATE; 507 builder.startElement(te, StandardNames.XDT_UNTYPED, 0, 0); 508 builder.attribute(pool.allocate("", "", "match"), StandardNames.XDT_UNTYPED_ATOMIC, "/", 0, 0); 509 builder.startContent(); 510 511 builder.graftElement(this); 512 513 builder.endElement(); 514 builder.endElement(); 515 builder.endDocument(); 516 builder.close(); 517 518 return (DocumentImpl)builder.getCurrentRoot(); 519 } catch (XPathException err) { 520 err.setLocator(this); 522 throw err; 523 } 524 525 } 526 527 532 533 public int getConstructType() { 534 return Location.LITERAL_RESULT_ELEMENT; 535 } 536 537 542 543 public int getObjectNameCode() { 544 return resultNameCode; 545 } 546 547 555 556 public Object getProperty(String name) { 557 if (name.equals("name")) { 558 return getDisplayName(); 559 } 560 return null; 561 } 562 563 } 564 | Popular Tags |