AttributeNode.java [plain text]
package gnu.xml.transform;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import gnu.xml.xpath.Expr;
final class AttributeNode
extends TemplateNode
{
final TemplateNode name;
final TemplateNode namespace;
final Node source;
AttributeNode(TemplateNode children, TemplateNode next, TemplateNode name,
TemplateNode namespace, Node source)
{
super(children, next);
this.name = name;
this.namespace = namespace;
this.source = source;
}
TemplateNode clone(Stylesheet stylesheet)
{
return new AttributeNode((children == null) ? null :
children.clone(stylesheet),
(next == null) ? null : next.clone(stylesheet),
name.clone(stylesheet),
(namespace == null) ? null :
namespace.clone(stylesheet),
source);
}
void doApply(Stylesheet stylesheet, QName mode,
Node context, int pos, int len,
Node parent, Node nextSibling)
throws TransformerException
{
Document doc = (parent instanceof Document) ? (Document) parent :
parent.getOwnerDocument();
DocumentFragment fragment = doc.createDocumentFragment();
name.apply(stylesheet, mode,
context, pos, len,
fragment, null);
String nameValue = Expr.stringValue(fragment);
String namespaceValue = null;
if (namespace != null)
{
fragment = doc.createDocumentFragment();
namespace.apply(stylesheet, mode,
context, pos, len,
fragment, null);
namespaceValue = Expr.stringValue(fragment);
if (namespaceValue.length() == 0)
{
namespaceValue = null;
}
}
String prefix = getPrefix(nameValue);
if (namespaceValue == null)
{
if (prefix != null)
{
if (XMLConstants.XML_NS_PREFIX.equals(prefix))
{
namespaceValue = XMLConstants.XML_NS_URI;
}
else
{
namespaceValue = source.lookupNamespaceURI(prefix);
}
}
}
else
{
if (prefix != null)
{
String ns2 = source.lookupNamespaceURI(prefix);
if (ns2 != null && !ns2.equals(namespaceValue))
{
prefix = null;
int ci = nameValue.indexOf(':');
nameValue = nameValue.substring(ci + 1);
}
}
}
if (prefix == null)
{
prefix = source.lookupPrefix(namespaceValue);
if (prefix != null)
{
nameValue = prefix + ":" + nameValue;
}
else
{
if (namespaceValue != null)
{
prefix = inventPrefix(parent);
nameValue = prefix + ":" + nameValue;
}
}
}
NamedNodeMap attrs = parent.getAttributes();
boolean insert = true;
if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceValue) ||
XMLConstants.XMLNS_ATTRIBUTE.equals(nameValue) ||
nameValue.startsWith("xmlns:"))
{
insert = false;
}
if (prefix != null && namespaceValue == null)
{
insert = false;
}
if (parent.getNodeType() == Node.ELEMENT_NODE &&
parent.getFirstChild() != null)
{
insert = false;
}
if (insert)
{
Attr attr = (namespaceValue != null) ?
doc.createAttributeNS(namespaceValue, nameValue) :
doc.createAttribute(nameValue);
if (attrs != null)
{
if (namespace != null)
{
attrs.setNamedItemNS(attr);
}
else
{
attrs.setNamedItem(attr);
}
}
if (children != null)
{
children.apply(stylesheet, mode,
context, pos, len,
attr, null);
}
}
if (next != null)
{
next.apply(stylesheet, mode,
context, pos, len,
parent, nextSibling);
}
}
final String getPrefix(String name)
{
int ci = name.indexOf(':');
return (ci == -1) ? null : name.substring(0, ci);
}
final String inventPrefix(Node parent)
{
String base = "ns";
int count = 0;
String ret = base + Integer.toString(count);
while (parent.lookupNamespaceURI(ret) != null)
{
count++;
ret = base + Integer.toString(count);
}
return ret;
}
public String toString()
{
StringBuffer buf = new StringBuffer(getClass().getName());
buf.append('[');
buf.append("name=");
buf.append(name);
buf.append(']');
return buf.toString();
}
}