context.expressionStart(this);
context.pushInScopeNamespaces();
if (newDocumentContext)
context.pushDocumentContext();
try {
MemTreeBuilder builder = context.getDocumentBuilder();
// declare namespaces
// if(namespaceDecls != null) {
// for(int i = 0; i < namespaceDecls.length; i++) {
// //if ("".equals(namespaceDecls[i].getNamespaceURI())) {
// // TODO: the specs are unclear here: should we throw XQST0085 or not?
// // context.inScopeNamespaces.remove(namespaceDecls[i].getLocalName());
//// if (context.inScopeNamespaces.remove(namespaceDecls[i].getLocalName()) == null)
//// throw new XPathException(getAS TNode(), "XQST0085 : can not undefine '" + namespaceDecls[i] + "'");
// //} else
// context.declareInScopeNamespace(namespaceDecls[i].getLocalName(), namespaceDecls[i].getNamespaceURI());
// }
// }
// AttributesImpl attrs = new AttributesImpl();
// if(attributes != null) {
// AttributeConstructor constructor;
// Sequence attrValues;
// QName attrQName;
// // first, search for xmlns attributes and declare in-scope namespaces
// for (int i = 0; i < attributes.length; i++) {
// constructor = attributes[i];
// if(constructor.isNamespaceDeclaration()) {
// int p = constructor.getQName().indexOf(':');
// if(p == Constants.STRING_NOT_FOUND)
// context.declareInScopeNamespace("", constructor.getLiteralValue());
// else {
// String prefix = constructor.getQName().substring(p + 1);
// context.declareInScopeNamespace(prefix, constructor.getLiteralValue());
// }
// }
// }
// // process the remaining attributes
// for (int i = 0; i < attributes.length; i++) {
// context.proceed(this, builder);
// constructor = attributes[i];
// attrValues = constructor.eval(contextSequence, contextItem);
// attrQName = QName.parse(context, constructor.getQName(), "");
// if (attrs.getIndex(attrQName.getNamespaceURI(), attrQName.getLocalName()) != -1)
// throw new XPathException(this, "XQST0040 '" + attrQName.getLocalName() + "' is a duplicate attribute name");
// attrs.addAttribute(attrQName.getNamespaceURI(), attrQName.getLocalName(),
// attrQName.getStringValue(), "CDATA", attrValues.getStringValue());
// }
// }
context.proceed(this, builder);
// evaluate element tag name
QName qn = null;
String tagName = name;
Sequence qnameSeq = null;
if (qnameExpr != null)
qnameSeq = qnameExpr.eval(contextSequence, contextItem);
// else
// qnameSeq = super.eval(contextSequence, contextItem);
if (qnameSeq != null) {
if(!qnameSeq.hasOne())
throw new XPathException(this, "Type error: the node name should evaluate to a single item");
Item qnitem = qnameSeq.itemAt(0);
if (qnitem instanceof QNameValue) {
qn = ((QNameValue)qnitem).getQName();
} else {
tagName = qnitem.getStringValue();
}
}
if (qn == null) {
if (tagName == null)
throw new XPathException(this, ErrorCodes.XPTY0004, "element name wasn't provided");
//Not in the specs but... makes sense
if(!XMLChar.isValidName(tagName))
throw new XPathException(this, ErrorCodes.XPTY0004, "'" + tagName + "' is not a valid element name");
try {
qn = QName.parse(context, tagName);
} catch (IllegalArgumentException e) {
throw new XPathException(this, ErrorCodes.XPTY0004, "'"+tagName+"' is not a valid element name");
}
}
//
// //Use the default namespace if specified
// /*
// if (qn.getPrefix() == null && context.inScopeNamespaces.get("xmlns") != null) {
// qn.setNamespaceURI((String)context.inScopeNamespaces.get("xmlns"));
// }
// */
// if (qn.getPrefix() == null && context.getInScopeNamespace("") != null) {
// qn.setNamespaceURI(context.getInScopeNamespace(""));
// }
// }
//
int nodeNr = builder.startElement(qn, null);
// process attributes
if (use_attribute_sets != null) {
((XSLContext)context).getXSLStylesheet()
.attributeSet(use_attribute_sets, contextSequence, contextItem);
}
for (Attribute attr : attributes) {
attr.eval(contextSequence, contextItem);
}
// add namespace declaration nodes
// if(namespaceDecls != null) {
// for(int i = 0; i < namespaceDecls.length; i++) {
// builder.namespaceNode(namespaceDecls[i]);
// }
// }
// // do we need to add a namespace declaration for the current node?
// if (qn.needsNamespaceDecl()) {
// if (context.getInScopePrefix(qn.getNamespaceURI()) == null) {
// String prefix = qn.getPrefix();
// if (prefix == null || prefix.length() == 0)
// prefix = "";
// context.declareInScopeNamespace(prefix, qn.getNamespaceURI());
// builder.namespaceNode(new QName(prefix, qn.getNamespaceURI(), "xmlns"));
// }
// } else if ((qn.getPrefix() == null || qn.getPrefix().length() == 0) &&
// context.getInheritedNamespace("") != null) {
// context.declareInScopeNamespace("", "");
// builder.namespaceNode(new QName("", "", "xmlns"));
// }
// process element contents
// if(content != null) {
// content.eval(contextSequence, contextItem);
// } else
super.eval(contextSequence, contextItem);
builder.endElement();
NodeImpl node = builder.getDocument().getNode(nodeNr);
return node;
} finally {
context.popInScopeNamespaces();
if (newDocumentContext)
context.popDocumentContext();