}
if (newDocumentContext)
context.pushDocumentContext();
NodeImpl node;
try {
MemTreeBuilder builder = context.getDocumentBuilder();
builder.setReplaceAttributeFlag(true);
context.proceed(this, builder);
QName qn = null;
String name = null;
if (qnameExpr != null) {
Sequence nameSeq = qnameExpr.eval(contextSequence, contextItem);
if (!nameSeq.hasOne())
throw new XPathException(this, "The name expression should evaluate to a single value");
Item qnItem = nameSeq.itemAt(0);
if (qnItem.getType() == Type.QNAME)
qn = ((QNameValue) qnItem).getQName();
else
name = nameSeq.getStringValue();
} else {
name = this.name;
}
if (qn == null) {
//Not in the specs but... makes sense
if(!XMLChar.isValidName(name))
throw new XPathException(this, ErrorCodes.XPTY0004,
"'" + name + "' is not a valid attribute name");
try {
qn = QName.parse(context, name, null);
} catch (IllegalArgumentException e) {
throw new XPathException(this, ErrorCodes.XPTY0004,
"'" + name + "' is not a valid attribute name");
}
}
String value = this.value;
Sequence valueSeq = null;
if (valueExpr != null) {
valueSeq = valueExpr.eval(contextSequence, contextItem);
} else {
context.pushDocumentContext();
valueSeq = super.eval(contextSequence, contextItem);
context.popDocumentContext();
}
if (!valueSeq.isEmpty()) {
StringBuilder buf = new StringBuilder();
for(SequenceIterator i = valueSeq.iterate(); i.hasNext(); ) {
Item next = i.nextItem();
buf.append(next.getStringValue());
if(i.hasNext())
buf.append(' ');
}
value = buf.toString();
}
if (value == null)
value = "";
node = null;
try {
int nodeNo = builder.addAttribute(qn, value);
node = builder.getDocument().getAttribute(nodeNo);
} catch (DOMException e) {
throw new XPathException(this, ErrorCodes.XQDY0025, e.getMessage());
}
} finally {
if (newDocumentContext)