1 package net.sf.saxon.instruct; 2 import net.sf.saxon.Err; 3 import net.sf.saxon.event.ReceiverOptions; 4 import net.sf.saxon.event.SequenceReceiver; 5 import net.sf.saxon.expr.*; 6 import net.sf.saxon.om.Item; 7 import net.sf.saxon.om.NamePool; 8 import net.sf.saxon.om.Orphan; 9 import net.sf.saxon.pattern.NodeKindTest; 10 import net.sf.saxon.style.StandardNames; 11 import net.sf.saxon.trans.StaticError; 12 import net.sf.saxon.trans.XPathException; 13 import net.sf.saxon.type.*; 14 import net.sf.saxon.value.StringValue; 15 import net.sf.saxon.value.Value; 16 import net.sf.saxon.value.Whitespace; 17 18 import java.io.PrintStream ; 19 20 30 31 public final class ValueOf extends SimpleNodeConstructor { 32 33 private int options; 34 private boolean isNumberingInstruction = false; private boolean noNodeIfEmpty; 36 37 public ValueOf(Expression select, boolean disable, boolean noNodeIfEmpty) { 38 this.select = select; 39 this.options = (disable ? ReceiverOptions.DISABLE_ESCAPING : 0); 40 this.noNodeIfEmpty = noNodeIfEmpty; 41 adoptChildExpression(select); 42 43 if (select instanceof StringValue) { 46 boolean special = false; 47 CharSequence val = ((StringValue)select).getStringValueCS(); 48 for (int k=0; k<val.length(); k++) { 49 char c = val.charAt(k); 50 if ((int)c<33 || (int)c>126 || 51 c=='<' || c=='>' || c=='&') { 52 special = true; 53 break; 54 } 55 } 56 if (!special) { 57 this.options |= ReceiverOptions.NO_SPECIAL_CHARS; 58 } 59 } 60 } 61 62 65 66 public void setIsNumberingInstruction() { 67 isNumberingInstruction = true; 68 } 69 70 73 74 public int getInstructionNameCode() { 75 if (isNumberingInstruction) { 76 return StandardNames.XSL_NUMBER; 77 } else if (select instanceof StringValue) { 78 return StandardNames.XSL_TEXT; 79 } else { 80 return StandardNames.XSL_VALUE_OF; 81 } 82 } 83 84 96 97 protected void promoteInst(PromotionOffer offer) throws XPathException { 98 super.promoteInst(offer); 99 } 100 101 public ItemType getItemType() { 102 return NodeKindTest.TEXT; 103 } 104 105 public int computeCardinality() { 106 if (noNodeIfEmpty) { 107 return StaticProperty.ALLOWS_ZERO_OR_ONE; 108 } else { 109 return StaticProperty.EXACTLY_ONE; 110 } 111 } 112 113 public void localTypeCheck(StaticContext env, ItemType contextItemType) { 114 115 } 116 117 127 128 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 129 if (select instanceof Value) { 131 SimpleType stype = null; 132 if (parentType instanceof SimpleType && whole) { 133 stype = (SimpleType)parentType; 134 } else if (parentType instanceof ComplexType && ((ComplexType)parentType).isSimpleContent()) { 135 stype = ((ComplexType)parentType).getSimpleContentType(); 136 } 137 if (whole && stype != null && !stype.isNamespaceSensitive()) { 138 XPathException err = stype.validateContent(((Value)select).getStringValue(), null, env.getConfiguration()); 140 if (err != null) { 141 err.setLocator(this); 142 throw err; 143 } 144 return; 145 } 146 if (parentType instanceof ComplexType && 147 !((ComplexType)parentType).isSimpleContent() && 148 !((ComplexType)parentType).isMixedContent() && 149 !Whitespace.isWhite(((Value)select).getStringValue())) { 150 StaticError err = new StaticError("Complex type " + parentType.getDescription() + 151 " does not allow text content " + 152 Err.wrap(((Value)select).getStringValue())); 153 err.setLocator(this); 154 err.setIsTypeError(true); 155 throw err; 156 } 157 } 158 } 159 160 public TailCall processLeavingTail(XPathContext context) throws XPathException { 161 SequenceReceiver out = context.getReceiver(); 162 Item item = select.evaluateItem(context); 163 if (item != null) { 164 out.characters(item.getStringValueCS(), locationId, options); 165 } 166 return null; 167 } 168 169 public Item evaluateItem(XPathContext context) throws XPathException { 170 try { 171 CharSequence val; 172 Item item = select.evaluateItem(context); 173 if (item == null) { 174 if (noNodeIfEmpty) { 175 return null; 176 } else { 177 val = ""; 178 } 179 } else { 180 val = item.getStringValueCS(); 181 } 182 Orphan o = new Orphan(context.getController().getConfiguration()); 183 o.setNodeKind(Type.TEXT); 184 o.setStringValue(val); 185 return o; 186 } catch (XPathException err) { 187 if (err.getLocator() == null) { 188 err.setLocator(this); 189 } 190 throw err; 191 } 192 } 193 194 197 198 public void display(int level, NamePool pool, PrintStream out) { 199 out.println(ExpressionTool.indent(level) + "value-of"); 200 select.display(level+1, pool, out); 201 } 202 } 203 204 | Popular Tags |