1 package net.sf.saxon.functions; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.om.*; 4 import net.sf.saxon.sort.DocumentOrderIterator; 5 import net.sf.saxon.sort.LocalOrderComparer; 6 import net.sf.saxon.trans.XPathException; 7 import net.sf.saxon.value.AtomicValue; 8 import net.sf.saxon.value.Cardinality; 9 10 11 18 19 20 public class Id extends SystemFunction { 21 22 private boolean isSingletonId = false; 23 24 27 28 public Expression simplify(StaticContext env) throws XPathException { 29 Id id = (Id)super.simplify(env); 30 if (argument.length == 1) { 31 id.addContextDocumentArgument(1, "id"); 32 } 33 return id; 34 } 35 36 39 40 public void checkArguments(StaticContext env) throws XPathException { 41 super.checkArguments(env); 42 Optimizer opt = env.getConfiguration().getOptimizer(); 43 argument[0] = ExpressionTool.unsorted(opt, argument[0], false); 44 isSingletonId = !Cardinality.allowsMany(argument[0].getCardinality()); 45 } 46 47 50 51 public Expression preEvaluate(StaticContext env) { 52 return this; 53 } 54 55 60 61 public int computeSpecialProperties() { 62 int prop = StaticProperty.ORDERED_NODESET | 63 StaticProperty.SINGLE_DOCUMENT_NODESET | 64 StaticProperty.NON_CREATIVE; 65 if ((getNumberOfArguments() == 1) || 66 (argument[1].getSpecialProperties() & StaticProperty.CONTEXT_DOCUMENT_NODESET) != 0) { 67 prop |= StaticProperty.CONTEXT_DOCUMENT_NODESET; 68 } 69 return prop; 70 } 71 72 75 76 public SequenceIterator iterate(XPathContext context) throws XPathException { 77 78 NodeInfo arg1 = (NodeInfo)argument[1].evaluateItem(context); 79 arg1 = arg1.getRoot(); 80 if (!(arg1 instanceof DocumentInfo)) { 81 dynamicError("In the id() function," + 82 " the tree being searched must be one whose root is a document node", context); 83 return null; 84 } 85 DocumentInfo doc = (DocumentInfo)arg1; 86 87 if (isSingletonId) { 88 AtomicValue arg = (AtomicValue)argument[0].evaluateItem(context); 89 if (arg==null) { 90 return EmptyIterator.getInstance(); 91 } 92 String idrefs = arg.getStringValue(); 93 if (idrefs.indexOf(0x20)>=0 || 94 idrefs.indexOf(0x09)>=0 || 95 idrefs.indexOf(0x0a)>=0 || 96 idrefs.indexOf(0x0d)>=0) { 97 StringTokenIterator tokens = new StringTokenIterator(idrefs); 98 IdMappingFunction map = new IdMappingFunction(); 99 map.document = doc; 100 SequenceIterator result = new MappingIterator(tokens, map, null); 101 return new DocumentOrderIterator(result, LocalOrderComparer.getInstance()); 102 } else { 103 return SingletonIterator.makeIterator(doc.selectID(idrefs)); 104 } 105 } else { 106 SequenceIterator idrefs = argument[0].iterate(context); 107 IdMappingFunction map = new IdMappingFunction(); 108 map.document = doc; 109 SequenceIterator result = new MappingIterator(idrefs, map, null); 110 return new DocumentOrderIterator(result, LocalOrderComparer.getInstance()); 111 } 112 } 113 114 private static class IdMappingFunction implements MappingFunction { 115 116 public DocumentInfo document; 117 118 122 123 public Object map(Item item, XPathContext c) throws XPathException { 124 125 String idrefs = item.getStringValue().trim(); 126 127 130 if (idrefs.indexOf(0x20)>=0 || 131 idrefs.indexOf(0x09)>=0 || 132 idrefs.indexOf(0x0a)>=0 || 133 idrefs.indexOf(0x0d)>=0) { 134 StringTokenIterator tokens = new StringTokenIterator(idrefs); 135 IdMappingFunction submap = new IdMappingFunction(); 136 submap.document = document; 137 return new MappingIterator(tokens, submap, null); 138 139 } else { 140 return document.selectID(idrefs); 141 } 142 } 143 } 144 145 } 146 147 148 149 150 | Popular Tags |