in src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java [663:880]
protected void serializeAttList(Element node) throws SAXException {
NamedNodeMap atts = node.getAttributes();
int nAttrs = atts.getLength();
for (int i = 0; i < nAttrs; i++) {
Node attr = atts.item(i);
String localName = attr.getLocalName();
String attrName = attr.getNodeName();
String attrPrefix = attr.getPrefix() == null ? "" : attr.getPrefix();
String attrValue = attr.getNodeValue();
// Determine the Attr's type.
String type = null;
if (fIsLevel3DOM) {
type = ((Attr) attr).getSchemaTypeInfo().getTypeName();
}
type = type == null ? "CDATA" : type;
String attrNS = attr.getNamespaceURI();
if (attrNS !=null && attrNS.length() == 0) {
attrNS=null;
// we must remove prefix for this attribute
attrName=attr.getLocalName();
}
boolean isSpecified = ((Attr) attr).getSpecified();
boolean addAttr = true;
boolean applyFilter = false;
boolean xmlnsAttr =
attrName.equals("xmlns") || attrName.startsWith("xmlns:");
// well-formed=true
if ((fFeatures & WELLFORMED) != 0) {
isAttributeWellFormed(attr);
}
//-----------------------------------------------------------------
// start Attribute namespace fixup
//-----------------------------------------------------------------
// namespaces=true, normalize all non-namespace attributes
// Step 3. Attribute
if ((fFeatures & NAMESPACES) != 0 && !xmlnsAttr) {
// If the Attr has a namespace URI
if (attrNS != null) {
attrPrefix = attrPrefix == null ? "" : attrPrefix;
String declAttrPrefix = fNSBinder.getPrefix(attrNS);
String declAttrNS = fNSBinder.getURI(attrPrefix);
// attribute has no prefix (default namespace decl does not apply to
// attributes)
// OR
// attribute prefix is not declared
// OR
// conflict: attribute has a prefix that conflicts with a binding
if ("".equals(attrPrefix) || "".equals(declAttrPrefix)
|| !attrPrefix.equals(declAttrPrefix)) {
// namespaceURI matches an in scope declaration of one or
// more prefixes
if (declAttrPrefix != null && !"".equals(declAttrPrefix)) {
// pick the prefix that was found and change attribute's
// prefix and nodeName.
attrPrefix = declAttrPrefix;
if (declAttrPrefix.length() > 0 ) {
attrName = declAttrPrefix + ":" + localName;
} else {
attrName = localName;
}
} else {
// The current prefix is not null and it has no in scope
// declaration
if (attrPrefix != null && !"".equals(attrPrefix)
&& declAttrNS == null) {
// declare this prefix
if ((fFeatures & NAMESPACEDECLS) != 0) {
fSerializer.addAttribute(XMLNS_URI, attrPrefix,
XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
attrNS);
fNSBinder.declarePrefix(attrPrefix, attrNS);
fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
}
} else {
// find a prefix following the pattern "NS" +index
// (starting at 1)
// make sure this prefix is not declared in the current
// scope.
int counter = 1;
attrPrefix = "NS" + counter++;
while (fLocalNSBinder.getURI(attrPrefix) != null) {
attrPrefix = "NS" + counter++;
}
// change attribute's prefix and Name
attrName = attrPrefix + ":" + localName;
// create a local namespace declaration attribute
// Add the xmlns declaration attribute
if ((fFeatures & NAMESPACEDECLS) != 0) {
fSerializer.addAttribute(XMLNS_URI, attrPrefix,
XMLNS_PREFIX + ":" + attrPrefix, "CDATA",
attrNS);
fNSBinder.declarePrefix(attrPrefix, attrNS);
fLocalNSBinder.declarePrefix(attrPrefix, attrNS);
}
}
}
}
} else { // if the Attr has no namespace URI
// Attr has no localName
if (localName == null) {
// DOM Level 1 node!
String msg = Utils.messages.createMessage(
MsgKey.ER_NULL_LOCAL_ELEMENT_NAME,
new Object[] { attrName });
if (fErrorHandler != null) {
fErrorHandler
.handleError(new DOMErrorImpl(
DOMError.SEVERITY_ERROR, msg,
MsgKey.ER_NULL_LOCAL_ELEMENT_NAME, null,
null, null));
}
} else { // uri=null and no colon
// attr has no namespace URI and no prefix
// no action is required, since attrs don't use default
}
}
}
// discard-default-content=true
// Default attr's are not passed to the filter and this contraint
// is applied only when discard-default-content=true
// What about default xmlns attributes???? check for xmlnsAttr
if ((((fFeatures & DISCARDDEFAULT) != 0) && isSpecified)
|| ((fFeatures & DISCARDDEFAULT) == 0)) {
applyFilter = true;
} else {
addAttr = false;
}
if (applyFilter) {
// apply the filter for Attributes that are not default attributes
// or namespace decl attributes
if (fFilter != null
&& (fFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)
!= 0) {
if (!xmlnsAttr) {
short code = fFilter.acceptNode(attr);
switch (code) {
case NodeFilter.FILTER_REJECT :
case NodeFilter.FILTER_SKIP :
addAttr = false;
break;
default : //fall through..
}
}
}
}
// if the node is a namespace node
if (addAttr && xmlnsAttr) {
// If namespace-declarations=true, add the node , else don't add it
if ((fFeatures & NAMESPACEDECLS) != 0) {
// The namespace may have been fixed up, in that case don't add it.
if (localName != null && !"".equals(localName)) {
fSerializer.addAttribute(attrNS, localName, attrName, type, attrValue);
}
}
} else if (
addAttr && !xmlnsAttr) { // if the node is not a namespace node
// If namespace-declarations=true, add the node with the Attr nodes namespaceURI
// else add the node setting it's namespace to null or else the serializer will later
// attempt to add a xmlns attr for the prefixed attribute
if (((fFeatures & NAMESPACEDECLS) != 0) && (attrNS != null)) {
fSerializer.addAttribute(
attrNS,
localName,
attrName,
type,
attrValue);
} else {
fSerializer.addAttribute(
"",
localName,
attrName,
type,
attrValue);
}
}
//
if (xmlnsAttr && ((fFeatures & NAMESPACEDECLS) != 0)) {
int index;
// Use "" instead of null, as Xerces likes "" for the
// name of the default namespace. Fix attributed
// to "Steven Murray" <smurray@ebt.com>.
String prefix =
(index = attrName.indexOf(":")) < 0
? ""
: attrName.substring(index + 1);
if (!"".equals(prefix)) {
fSerializer.namespaceAfterStartElement(prefix, attrValue);
}
}
}
}