1 package com.icl.saxon.functions; 2 import com.icl.saxon.*; 3 import com.icl.saxon.om.*; 4 import com.icl.saxon.tinytree.TinyBuilder; 5 import com.icl.saxon.tree.AttributeCollection; 6 import com.icl.saxon.expr.*; 7 import com.icl.saxon.output.*; 8 import com.icl.saxon.pattern.AnyNodeTest; 9 import com.icl.saxon.om.Axis; 10 import javax.xml.transform.TransformerException; 11 import java.util.*; 12 import java.text.*; 13 import org.w3c.xsl.XSLTContext; 14 15 24 25 26 27 public class Extensions { 28 29 30 public static void pauseTracing(Context c) { 31 c.getController().pauseTracing(true); 32 } 33 public static void resumeTracing(Context c) { 34 c.getController().pauseTracing(false); 35 } 36 37 41 42 public static NodeSetValue nodeSet(Context c, Value frag) throws XPathException { 43 if (frag instanceof SingletonNodeSet) { 44 ((SingletonNodeSet)frag).allowGeneralUse(); 45 } 46 if (frag instanceof NodeSetValue) { 47 return (NodeSetValue)frag; 48 } else { 49 TextFragmentValue v = 50 new TextFragmentValue(frag.asString(), "", c.getController()); 51 v.allowGeneralUse(); 52 return v; 53 } 54 } 55 56 59 60 public static NodeSetValue nodeset(Context c, Value frag) throws XPathException { 61 return nodeSet(c, frag); 62 } 63 64 67 68 public static String systemId(Context c) throws XPathException { 69 return c.getContextNodeInfo().getSystemId(); 70 } 71 72 76 77 public static double lineNumber(Context c) throws XPathException { 78 return c.getContextNodeInfo().getLineNumber(); 79 } 80 81 84 85 public static String baseUri(Context c) throws XPathException { 86 return c.getContextNodeInfo().getBaseURI(); 87 } 88 89 95 96 public static NodeEnumeration intersection(Context c, NodeEnumeration p1, NodeEnumeration p2) throws XPathException { 97 return new IntersectionEnumeration(p1, p2, c.getController()); 98 } 99 100 106 107 public static NodeEnumeration difference(Context c, NodeEnumeration p1, NodeEnumeration p2) throws XPathException { 108 return new DifferenceEnumeration(p1, p2, c.getController()); 109 } 110 111 117 118 public static boolean hasSameNodes(Context context, NodeEnumeration p1, NodeEnumeration p2) throws XPathException { 119 NodeEnumeration e1 = p1; 120 NodeEnumeration e2 = p2; 121 Controller controller = context.getController(); 122 if (!e1.isSorted()) { 123 e1 = (new NodeSetExtent(e1, controller)).sort().enumerate(); 124 } 125 if (!e2.isSorted()) { 126 e2 = (new NodeSetExtent(e2, controller)).sort().enumerate(); 127 } 128 while (e1.hasMoreElements()) { 129 if (!e2.hasMoreElements()) { 130 return false; 131 } 132 if (!e1.nextElement().isSameNode(e2.nextElement())) { 133 return false; 134 } 135 } 136 if (e2.hasMoreElements()) { 137 return false; 138 } 139 return true; 140 } 141 142 143 151 152 public static Value IF (Value test, Value thenValue, Value elseValue ) throws XPathException { 153 return ( test.asBoolean() ? thenValue : elseValue ); 154 } 155 156 159 160 public static Value evaluate (Context c, String expr) throws XPathException { 161 StaticContext env = c.getStaticContext().makeRuntimeContext( 162 c.getController().getNamePool()); 163 Expression e = Expression.make(expr, env); 164 return e.evaluate(c); 165 } 166 167 170 171 public static Value eval (Context c, Expression expr) throws XPathException { 172 return expr.evaluate(c); 173 } 174 175 179 180 public static Value expression (Context c, String expr) throws XPathException { 181 StaticContext env = c.getStaticContext().makeRuntimeContext( 182 c.getController().getNamePool()); 183 Expression e1 = Expression.make(expr, env); 184 Expression e2 = e1.reduce(Context.VARIABLES, c).simplify(); 186 return new ObjectValue(e2); 187 } 188 189 192 193 public static double sum (Context context, 194 NodeEnumeration nsv, 195 Expression expression) throws XPathException { 196 double total = 0.0; 197 Context c = context.newContext(); 198 NodeEnumeration v; 199 if (nsv instanceof LastPositionFinder) { 200 v = nsv; 201 } else { 202 v = new LookaheadEnumerator(nsv); 203 } 204 c.setLastPositionFinder((LastPositionFinder)v); 205 int pos = 1; 206 while (v.hasMoreElements()) { 207 c.setContextNode(v.nextElement()); 208 c.setPosition(pos++); 209 double x = expression.evaluateAsNumber(c); 210 total += x; 211 } 212 return total; 213 } 214 215 218 219 public static double max (NodeEnumeration nsv) throws XPathException { 220 return com.icl.saxon.exslt.Math.max(nsv); 221 } 222 223 224 227 228 public static double max (Context context, 229 NodeEnumeration nsv, 230 Expression expression) throws XPathException { 231 double max = Double.NEGATIVE_INFINITY; 232 Context c = context.newContext(); 233 NodeEnumeration v; 234 if (nsv instanceof LastPositionFinder) { 235 v = nsv; 236 } else { 237 v = new LookaheadEnumerator(nsv); 238 } 239 c.setLastPositionFinder((LastPositionFinder)v); 240 int pos = 1; 241 while (v.hasMoreElements()) { 242 c.setContextNode(v.nextElement()); 243 c.setPosition(pos++); 244 double x = expression.evaluateAsNumber(c); 245 if (x>max) max = x; 246 } 247 return max; 248 } 249 250 253 254 public static double min (NodeEnumeration nsv) throws XPathException { 255 return com.icl.saxon.exslt.Math.min(nsv); 256 } 257 258 261 262 public static double min (Context context, 263 NodeEnumeration nsv, 264 Expression expression) throws XPathException { 265 double min = Double.POSITIVE_INFINITY; 266 Context c = context.newContext(); 267 NodeEnumeration v; 268 if (nsv instanceof LastPositionFinder) { 269 v = nsv; 270 } else { 271 v = new LookaheadEnumerator(nsv); 272 } 273 c.setLastPositionFinder((LastPositionFinder)v); 274 int pos = 1; 275 while (v.hasMoreElements()) { 276 c.setContextNode(v.nextElement()); 277 c.setPosition(pos++); 278 double x = expression.evaluateAsNumber(c); 279 if (x<min) min = x; 280 } 281 return min; 282 } 283 284 287 288 public static NodeSetValue highest (Context c, NodeEnumeration nsv) throws XPathException { 289 return com.icl.saxon.exslt.Math.highest(c, nsv); 290 } 291 292 293 296 297 public static NodeEnumeration highest (Context context, 298 NodeEnumeration nsv, 299 Expression expression) throws XPathException { 300 double max = Double.NEGATIVE_INFINITY; 301 Context c = context.newContext(); 302 NodeInfo highest = null; 303 NodeEnumeration v; 304 if (nsv instanceof LastPositionFinder) { 305 v = nsv; 306 } else { 307 v = new LookaheadEnumerator(nsv); 308 } 309 c.setLastPositionFinder((LastPositionFinder)v); 310 int pos = 1; 311 while (v.hasMoreElements()) { 312 c.setContextNode(v.nextElement()); 313 c.setPosition(pos++); 314 double x = expression.evaluateAsNumber(c); 315 if (x>max) { 316 max = x; 317 highest = c.getContextNodeInfo(); 318 } 319 } 320 return new SingletonEnumeration(highest); 321 } 322 323 326 327 public static NodeSetValue lowest (Context c, NodeEnumeration nsv) throws XPathException { 328 return com.icl.saxon.exslt.Math.lowest(c, nsv); 329 } 330 331 334 335 public static NodeEnumeration lowest (Context context, 336 NodeEnumeration nsv, 337 Expression expression) throws XPathException { 338 double min = Double.POSITIVE_INFINITY; 339 Context c = context.newContext(); 340 NodeInfo lowest = null; 341 NodeEnumeration v; 342 if (nsv instanceof LastPositionFinder) { 343 v = nsv; 344 } else { 345 v = new LookaheadEnumerator(nsv); 346 } 347 c.setLastPositionFinder((LastPositionFinder)v); 348 int pos = 1; 349 while (v.hasMoreElements()) { 350 c.setContextNode(v.nextElement()); 351 c.setPosition(pos++); 352 double x = expression.evaluateAsNumber(c); 353 if (x<min) { 354 min = x; 355 lowest = c.getContextNodeInfo(); 356 } 357 } 358 return new SingletonEnumeration(lowest); 359 } 360 361 364 365 public static NodeEnumeration distinct(Context context, NodeEnumeration in) throws XPathException { 366 return new DistinctEnumeration(in, context.getController()); 367 } 368 369 373 374 public static NodeEnumeration distinct(Context context, 375 NodeEnumeration in, 376 Expression exp) throws XPathException { 377 return new DistinctEnumeration(context, in, exp); 378 } 379 380 383 384 public static NodeEnumeration closure (Context c, 385 NodeEnumeration enum, Expression expr) throws XPathException { 386 387 NodeEnumeration result = EmptyEnumeration.getInstance(); 388 Controller controller = c.getController(); 389 while(enum.hasMoreElements()) { 390 NodeInfo node = enum.nextElement(); 391 Context c2 = c.newContext(); 392 c2.setContextNode(node); 393 c2.setCurrentNode(node); 394 c2.setPosition(1); 395 c2.setLast(1); 396 NodeEnumeration next = 397 new UnionEnumeration( 398 new SingletonEnumeration(node), 399 closure(c2, expr.enumerate(c2, false), expr), 400 controller); 401 result = new UnionEnumeration(result, next, controller); 402 } 403 return result; 404 } 405 406 410 411 public static NodeEnumeration leading (Context context, 412 NodeEnumeration in, Expression exp) throws XPathException { 413 return new FilterEnumerator(in, exp, context.newContext(), true); 414 } 415 416 420 421 public static NodeSetValue before ( 422 Context context, 423 NodeSetValue ns1, 424 NodeSetValue ns2) throws XPathException { 425 426 NodeInfo test = null; 427 NodeEnumeration enum2 = ns2.enumerate(); 428 while (enum2.hasMoreElements()) { 429 test = enum2.nextElement(); 430 } 431 if (test==null) { 432 return new EmptyNodeSet(); 433 } 434 Controller controller = context.getController(); 435 436 Vector v = new Vector(); 437 NodeEnumeration enum = ns1.enumerate(); 438 while (enum.hasMoreElements()) { 439 NodeInfo node = enum.nextElement(); 440 if (controller.compare(node, test) < 0) { 441 v.addElement(node); 442 } else { 443 break; 444 } 445 } 446 return new NodeSetExtent(v, controller); 447 448 } 449 450 454 455 public static NodeSetValue after ( 456 Context context, 457 NodeSetValue ns1, NodeSetValue ns2) throws XPathException { 458 459 NodeInfo test = ns2.getFirst(); 460 if (test==null) { 461 return new EmptyNodeSet(); 462 } 463 Controller controller = context.getController(); 464 465 Vector v = new Vector(); 466 NodeEnumeration enum = ns1.enumerate(); 467 boolean pastLimit = false; 468 while (enum.hasMoreElements()) { 469 NodeInfo node = enum.nextElement(); 470 if (pastLimit) { 471 v.addElement(node); 472 } else if (controller.compare(node, test) > 0) { 473 pastLimit = true; 474 v.addElement(node); 475 } 476 } 477 return new NodeSetExtent(v, controller); 478 479 } 480 481 484 485 public static boolean exists (Context context, 486 NodeEnumeration nsv, 487 Expression expression) throws XPathException { 488 return new FilterEnumerator(nsv, expression, context.newContext(), false) 489 .hasMoreElements(); 490 } 491 492 495 496 public static boolean forAll (Context context, 497 NodeEnumeration nsv, 498 Expression expression) throws XPathException { 499 Not notexp = new Not(); 500 notexp.addArgument(expression); 501 return !(new FilterEnumerator(nsv, notexp, context.newContext(), false) 502 .hasMoreElements()); 503 } 504 505 506 509 510 public static NodeEnumeration range(Context context, double start, double finish) throws XPathException { 511 int a = (int)Round.round(start); 512 int b = (int)Round.round(finish); 513 514 try { 515 TinyBuilder builder = new TinyBuilder(); 516 NamePool pool = context.getController().getNamePool(); 517 int[] namespaces = new int[1]; 518 namespaces[0] = pool.getNamespaceCode("saxon", Namespace.SAXON); 519 int saxonRange = pool.allocate("saxon", Namespace.SAXON, "range"); 520 builder.setNamePool(pool); 521 builder.startDocument(); 522 AttributeCollection emptyAtts = new AttributeCollection(pool); 523 524 for (int i=a; i<=b; i++) { 525 builder.startElement(saxonRange, emptyAtts, namespaces, 1); 526 String n = i+""; 527 builder.characters(n.toCharArray(), 0, n.length()); 528 builder.endElement(saxonRange); 529 } 530 531 builder.endDocument(); 532 DocumentInfo doc = builder.getCurrentDocument(); 533 return doc.getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()); 534 535 } catch (TransformerException err) { 536 throw new XPathException(err); 537 } 538 539 } 540 541 545 546 public static NodeEnumeration tokenize(Context context, String s) throws XPathException { 547 548 try { 549 Builder builder = context.getController().makeBuilder(); 550 NamePool pool = context.getController().getNamePool(); 551 builder.startDocument(); 552 int[] namespaces = new int[1]; 553 namespaces[0] = pool.getNamespaceCode("saxon", Namespace.SAXON); 554 int saxonToken = pool.allocate("saxon", Namespace.SAXON, "token"); 555 AttributeCollection emptyAtts = new AttributeCollection(pool); 556 557 StringTokenizer st = new StringTokenizer(s); 558 while (st.hasMoreTokens()) { 559 builder.startElement(saxonToken, emptyAtts, namespaces, 1); 560 String n = st.nextToken(); 561 builder.characters(n.toCharArray(), 0, n.length()); 562 builder.endElement(saxonToken); 563 } 564 565 builder.endDocument(); 566 DocumentInfo doc = builder.getCurrentDocument(); 567 return doc.getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()); 568 } catch (TransformerException err) { 569 throw new XPathException(err); 570 } 571 } 572 573 578 579 public static NodeEnumeration tokenize(Context context, String s, String delim) throws XPathException { 580 try { 581 Builder builder = context.getController().makeBuilder(); 582 NamePool pool = context.getController().getNamePool(); 583 builder.setNamePool(pool); 584 builder.startDocument(); 585 int[] namespaces = new int[1]; 586 namespaces[0] = pool.getNamespaceCode("saxon", Namespace.SAXON); 587 int saxonToken = pool.allocate("saxon", Namespace.SAXON, "token"); 588 AttributeCollection emptyAtts = new AttributeCollection(pool); 589 590 StringTokenizer st = new StringTokenizer(s, delim); 591 while (st.hasMoreTokens()) { 592 builder.startElement(saxonToken, emptyAtts, namespaces, 1); 593 String n = st.nextToken(); 594 builder.characters(n.toCharArray(), 0, n.length()); 595 builder.endElement(saxonToken); 596 } 597 598 builder.endDocument(); 599 DocumentInfo doc = builder.getCurrentDocument(); 600 return doc.getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()); 601 } catch (TransformerException err) { 602 throw new XPathException(err); 603 } 604 } 605 606 607 610 611 public static String path(Context c) throws XPathException { 612 return Navigator.getPath(c.getContextNodeInfo()); 613 } 614 615 618 619 private static final String[] NODE_TYPE_NAMES = 620 {"Node", "Element", "Attribute", "Text", "?", "?", "?", 621 "Processing Instruction", "Comment", "Root", "?", "?", "?", "Namespace"}; 622 623 626 627 public static String showNodeset(Context c, NodeSetValue in) throws XPathException { 628 System.err.println("Node-set contents at line " + c.getStaticContext().getLineNumber() + " ["); 629 NodeEnumeration enum = in.enumerate(c, true); 630 int count = 0; 631 while (enum.hasMoreElements()) { 632 count++; 633 NodeInfo next = enum.nextElement(); 634 String typeName = NODE_TYPE_NAMES[next.getNodeType()]; 635 System.err.println(" " + typeName + " " + 636 next.getDisplayName() + " " + 637 Navigator.getPath(next) + " " + 638 next.generateId()); 639 } 640 System.err.println("] (Total number of nodes: " + count + ")"); 641 return ""; 642 } 643 644 645 648 649 public static boolean isNull(Object x) throws XPathException { 650 return x==null; 651 } 652 653 654 657 658 public static void setUserData(Context c, String name, Value value) throws XPathException { 659 c.getController().setUserData( 661 (c.getContextNodeInfo()), name, value); 662 } 663 664 667 668 public static Value getUserData(Context c, String name) throws XPathException { 669 Object o = c.getController().getUserData( 670 (c.getContextNodeInfo()), name); 671 if (o==null) return new StringValue(""); 673 if (o instanceof Value) return (Value)o; 674 return new ObjectValue(o); 675 } 676 677 680 681 public static Context getContext(Context c) { 682 return c; 683 } 684 685 690 691 public static String getPseudoAttribute(Context c, String name) { 692 NodeInfo pi = c.getContextNodeInfo(); 693 if (pi.getNodeType() != NodeInfo.PI) return ""; 694 String val = ProcInstParser.getPseudoAttribute(pi.getStringValue(), name); 695 if (val==null) return ""; 696 return val; 697 } 698 699 700 701 } 702 703 704 705 706 707 | Popular Tags |