// check if changes are only for attributes and close tag
boolean tagNameUnchanged = false;
if (newRegions != null) {
Iterator e = newRegions.iterator();
while (e.hasNext()) {
ITextRegion region = (ITextRegion) e.next();
String regionType = region.getType();
if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME || regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS || regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
continue;
if (regionType == DOMRegionContext.XML_TAG_CLOSE) {
// change from empty tag may have impact on structure
if (!element.isEmptyTag())
continue;
}
else if (regionType == DOMRegionContext.XML_TAG_NAME || isNestedTagName(regionType)) {
String oldTagName = element.getTagName();
String newTagName = flatNode.getText(region);
if (oldTagName != null && newTagName != null && oldTagName.equals(newTagName)) {
// the tag name is unchanged
tagNameUnchanged = true;
continue;
}
}
// other region has changed
changeStructuredDocumentRegion(flatNode);
return;
}
}
if (oldRegions != null) {
Iterator e = oldRegions.iterator();
while (e.hasNext()) {
ITextRegion region = (ITextRegion) e.next();
String regionType = region.getType();
if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME || regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS || regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
continue;
if (regionType == DOMRegionContext.XML_TAG_CLOSE) {
// change from empty tag may have impact on structure
if (!element.isEmptyTag())
continue;
}
else if (regionType == DOMRegionContext.XML_TAG_NAME || isNestedTagName(regionType)) {
// if new tag name is unchanged, it's OK
if (tagNameUnchanged)
continue;
}
// other region has changed
changeStructuredDocumentRegion(flatNode);
return;
}
}
// update attributes
ITextRegionList regions = flatNode.getRegions();
if (regions == null)
return; // error
NamedNodeMap attributes = element.getAttributes();
if (attributes == null)
return; // error
// first remove attributes
int regionIndex = 0;
int attrIndex = 0;
AttrImpl attr = null;
while (attrIndex < attributes.getLength()) {
attr = (AttrImpl) attributes.item(attrIndex);
if (attr == null) { // error
attrIndex++;
continue;
}
ITextRegion nameRegion = attr.getNameRegion();
if (nameRegion == null) { // error
element.removeAttributeNode(attr);
continue;
}
boolean found = false;
for (int i = regionIndex; i < regions.size(); i++) {
ITextRegion region = regions.get(i);
if (region == nameRegion) {
regionIndex = i + 1; // next region
found = true;
break;
}
}
if (found) {
attrIndex++;
}
else {
element.removeAttributeNode(attr);
}
}
// insert or update attributes
attrIndex = 0; // reset to first
AttrImpl newAttr = null;
ITextRegion oldValueRegion = null;
Iterator e = regions.iterator();
while (e.hasNext()) {
ITextRegion region = (ITextRegion) e.next();
String regionType = region.getType();
if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
if (newAttr != null) {
// insert deferred new attribute
element.insertAttributeNode(newAttr, attrIndex++);
newAttr = null;