1 package net.sf.saxon.instruct; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.Controller; 5 import net.sf.saxon.event.Receiver; 6 import net.sf.saxon.expr.*; 7 import net.sf.saxon.om.*; 8 import net.sf.saxon.pattern.ContentTypeTest; 9 import net.sf.saxon.pattern.NodeKindTest; 10 import net.sf.saxon.style.StandardNames; 11 import net.sf.saxon.trans.DynamicError; 12 import net.sf.saxon.trans.StaticError; 13 import net.sf.saxon.trans.XPathException; 14 import net.sf.saxon.type.*; 15 import net.sf.saxon.value.QNameValue; 16 import net.sf.saxon.value.StringValue; 17 import net.sf.saxon.value.SequenceType; 18 import net.sf.saxon.value.AtomicValue; 19 20 import java.io.PrintStream ; 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 24 25 32 33 public class ComputedElement extends ElementCreator { 34 35 private Expression elementName; 36 private Expression namespace = null; 37 private NamespaceResolver nsContext; 38 private boolean allowNameAsQName; 39 private ItemType itemType; 40 41 54 public ComputedElement(Expression elementName, 55 Expression namespace, 56 NamespaceResolver nsContext, 57 SchemaType schemaType, 58 int validation, 59 boolean inheritNamespaces, 60 boolean allowQName) { 61 this.elementName = elementName; 62 this.namespace = namespace; 63 this.nsContext = nsContext; 64 setSchemaType(schemaType); 65 this.validation = validation; 66 this.inheritNamespaces = inheritNamespaces; 67 this.allowNameAsQName = allowQName; 68 adoptChildExpression(elementName); 69 adoptChildExpression(namespace); 70 } 71 72 public Expression simplify(StaticContext env) throws XPathException { 73 elementName = elementName.simplify(env); 74 if (namespace != null) { 75 namespace = namespace.simplify(env); 76 } 77 Configuration config = env.getConfiguration(); 78 setLazyConstruction(config.isLazyConstructionMode()); 79 80 if (getSchemaType() != null) { 81 itemType = new ContentTypeTest(Type.ELEMENT, getSchemaType(), config); 82 getSchemaType().analyzeContentExpression(content, Type.ELEMENT, env); 83 } else if (validation == Validation.STRIP || !config.isSchemaAware(Configuration.XML_SCHEMA)) { 84 itemType = new ContentTypeTest(Type.ELEMENT, 85 BuiltInSchemaFactory.getSchemaType(StandardNames.XDT_UNTYPED), 86 config); 87 } else { 88 itemType = NodeKindTest.ELEMENT; 91 } 92 return super.simplify(env); 93 } 94 95 public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException { 96 elementName = elementName.typeCheck(env, contextItemType); 97 adoptChildExpression(elementName); 98 RoleLocator role = new RoleLocator(RoleLocator.INSTRUCTION, "element/name", 0, null); 99 role.setSourceLocator(this); 100 if (allowNameAsQName) { 101 elementName = TypeChecker.staticTypeCheck(elementName, 103 SequenceType.SINGLE_ATOMIC, false, role, env); 104 } else { 105 elementName = TypeChecker.staticTypeCheck(elementName, 106 SequenceType.SINGLE_STRING, false, role, env); 107 } 108 if (namespace != null) { 109 namespace = namespace.typeCheck(env, contextItemType); 110 adoptChildExpression(namespace); 111 112 role = new RoleLocator(RoleLocator.INSTRUCTION, "attribute/namespace", 0, null); 113 role.setSourceLocator(this); 114 namespace = TypeChecker.staticTypeCheck( 115 namespace, SequenceType.SINGLE_STRING, false, role, env); 116 } 117 return super.typeCheck(env, contextItemType); 118 } 119 120 125 126 public ItemType getItemType() { 127 if (itemType == null) { 128 return super.getItemType(); 129 } 130 return itemType; 131 } 132 133 public Iterator iterateSubExpressions() { 134 ArrayList list = new ArrayList (8); 135 list.add(content); 136 list.add(elementName); 137 if (namespace != null) { 138 list.add(namespace); 139 } 140 return list.iterator(); 141 } 142 143 155 156 protected void promoteInst(PromotionOffer offer) throws XPathException { 157 elementName = doPromotion(elementName, offer); 158 if (namespace != null) { 159 namespace = doPromotion(namespace, offer); 160 } 161 super.promoteInst(offer); 162 } 163 164 171 172 public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException { 173 if (parentType instanceof SimpleType) { 174 StaticError err = new StaticError( 175 "Elements are not permitted here: the containing element has the simple type " + parentType.getDescription()); 176 err.setIsTypeError(true); 177 err.setLocator(this); 178 throw err; 179 } else if (((ComplexType)parentType).isSimpleContent()) { 180 StaticError err = new StaticError( 181 "Elements are not permitted here: the containing element has a complex type with simple content"); 182 err.setIsTypeError(true); 183 err.setLocator(this); 184 throw err; 185 } 186 } 189 190 191 198 199 public int getNameCode(XPathContext context) 200 throws XPathException, XPathException { 201 202 Controller controller = context.getController(); 203 NamePool pool = controller.getNamePool(); 204 205 String prefix; 206 String localName; 207 String uri; 208 209 AtomicValue nameValue = (AtomicValue)elementName.evaluateItem(context); 211 nameValue = nameValue.getPrimitiveValue(); 212 if (nameValue instanceof StringValue) { 213 CharSequence rawName = nameValue.getStringValueCS(); 215 try { 216 String [] parts = Name.getQNameParts(rawName); 217 prefix = parts[0]; 218 localName = parts[1]; 219 } catch (QNameException err) { 220 DynamicError err1 = new DynamicError("Invalid element name. " + err.getMessage(), this); 221 err1.setErrorCode((isXSLT(context) ? "XTDE0820" : "XQDY0074")); 222 err1.setXPathContext(context); 223 throw dynamicError(this, err1, context); 224 } 225 } else if (nameValue instanceof QNameValue && allowNameAsQName) { 226 localName = ((QNameValue)nameValue).getLocalName(); 228 uri = ((QNameValue)nameValue).getNamespaceURI(); 229 namespace = new StringValue(uri); 230 prefix = ((QNameValue)nameValue).getPrefix(); 231 } else { 232 DynamicError err = new DynamicError("Computed element name has incorrect type"); 233 err.setErrorCode((isXSLT(context) ? "XTDE0820" : "XPTY0004")); 234 err.setIsTypeError(true); 235 err.setXPathContext(context); 236 throw dynamicError(this, err, context); 237 } 238 239 if (namespace == null) { 240 uri = nsContext.getURIForPrefix(prefix, true); 241 if (uri == null) { 242 DynamicError err = new DynamicError("Undeclared prefix in element name: " + prefix, this); 243 err.setErrorCode((isXSLT(context) ? "XTDE0830" : "XQDY0074")); 244 err.setXPathContext(context); 245 throw dynamicError(this, err, context); 246 } 247 248 } else { 249 uri = namespace.evaluateAsString(context); 250 if (uri.equals("")) { 251 prefix = ""; 254 } 255 if (prefix.equals("xmlns")) { 256 prefix = "x-xmlns"; 258 } 259 } 260 261 return pool.allocate(prefix, uri, localName); 262 263 } 264 265 272 protected void outputNamespaceNodes(XPathContext context, Receiver out) 273 throws XPathException { 274 } 276 277 278 281 282 public int getInstructionNameCode() { 283 return StandardNames.XSL_ELEMENT; 284 } 285 286 289 290 public void display(int level, NamePool pool, PrintStream out) { 291 out.println(ExpressionTool.indent(level) + "element "); 292 out.println(ExpressionTool.indent(level + 1) + "name"); 293 elementName.display(level + 2, pool, out); 294 out.println(ExpressionTool.indent(level + 1) + "content"); 295 content.display(level + 1, pool, out); 296 } 297 } 298 299 | Popular Tags |