1 package net.sf.saxon.functions; 2 import net.sf.saxon.Controller; 3 import net.sf.saxon.expr.*; 4 import net.sf.saxon.om.DocumentInfo; 5 import net.sf.saxon.om.EmptyIterator; 6 import net.sf.saxon.om.Item; 7 import net.sf.saxon.om.SequenceIterator; 8 import net.sf.saxon.sort.DocumentOrderIterator; 9 import net.sf.saxon.sort.LocalOrderComparer; 10 import net.sf.saxon.style.StandardNames; 11 import net.sf.saxon.trans.KeyManager; 12 import net.sf.saxon.trans.XPathException; 13 import net.sf.saxon.value.AtomicValue; 14 import net.sf.saxon.value.Cardinality; 15 import net.sf.saxon.value.StringValue; 16 17 18 public class Idref extends SystemFunction { 19 20 23 24 public Expression simplify(StaticContext env) throws XPathException { 25 Idref f = (Idref)super.simplify(env); 26 f.addContextDocumentArgument(1, "idref"); 27 return f; 28 } 29 30 public void checkArguments(StaticContext env) throws XPathException { 31 super.checkArguments(env); 32 Optimizer opt = env.getConfiguration().getOptimizer(); 33 argument[0] = ExpressionTool.unsorted(opt, argument[0], false); 34 } 35 36 41 42 public int computeSpecialProperties() { 43 int prop = StaticProperty.ORDERED_NODESET | 44 StaticProperty.SINGLE_DOCUMENT_NODESET | 45 StaticProperty.NON_CREATIVE; 46 if ((getNumberOfArguments() == 1) || 47 (argument[1].getSpecialProperties() & StaticProperty.CONTEXT_DOCUMENT_NODESET) != 0) { 48 prop |= StaticProperty.CONTEXT_DOCUMENT_NODESET; 49 } 50 return prop; 51 } 52 53 56 57 public Expression preEvaluate(StaticContext env) { 58 return this; 59 } 60 61 64 65 public SequenceIterator iterate(XPathContext context) throws XPathException { 66 67 Controller controller = context.getController(); 68 69 Item arg2 = argument[1].evaluateItem(context); 70 if (!(arg2 instanceof DocumentInfo)) { 71 dynamicError("In the idref() function," + 72 " the context node must be in a tree whose root is a document node", context); 73 return null; 74 } 75 DocumentInfo doc = (DocumentInfo)arg2; 76 77 int fprint = StandardNames.XS_IDREFS; 78 79 83 Expression expression = argument[0]; 84 if (Cardinality.allowsMany(expression.getCardinality())) { 85 IdrefMappingFunction map = new IdrefMappingFunction(); 86 map.document = doc; 87 map.keyContext = context; 88 89 SequenceIterator keys = argument[0].iterate(context); 90 SequenceIterator allValues = new MappingIterator(keys, map, null); 91 return new DocumentOrderIterator(allValues, LocalOrderComparer.getInstance()); 92 } else { 93 AtomicValue keyValue = (AtomicValue)argument[0].evaluateItem(context); 94 if (keyValue == null) { 95 return EmptyIterator.getInstance(); 96 } 97 KeyManager keyManager = controller.getKeyManager(); 98 return keyManager.selectByKey(fprint, doc, keyValue, context); 99 100 } 101 } 102 103 private static class IdrefMappingFunction implements MappingFunction { 104 public DocumentInfo document; 105 public XPathContext keyContext; 106 107 110 111 public Object map(Item item, XPathContext context) throws XPathException { 112 KeyManager keyManager = keyContext.getController().getKeyManager(); 113 AtomicValue keyValue; 114 if (item instanceof AtomicValue) { 115 keyValue = (AtomicValue)item; 116 } else { 117 keyValue = new StringValue(item.getStringValue()); 118 } 119 return keyManager.selectByKey( 120 StandardNames.XS_IDREFS, document, keyValue, keyContext); 121 122 } 123 } 124 125 } 126 127 | Popular Tags |