public void startElement(String name, AttributeList atts) throws org.xml.sax.SAXException { //-- strip namespace prefix int idx = name.indexOf(':'); if (idx >= 0) { name = name.substring(idx+1); } StateInfo sInfo = null; boolean topLevel = false; //-- if we are currently in another element //-- definition...flag as complex content if (!_siStack.isEmpty()) { sInfo = (StateInfo)_siStack.peek(); sInfo.complex = true; } else { topLevel = true; } //-- create current holder for stateInformation sInfo = new StateInfo(); sInfo.topLevel = topLevel; _siStack.push(sInfo); //-- create element definition sInfo.element = new ElementDecl(_schema, name); //-- create attributes for (int i = 0; i < atts.getLength(); i++) { String attName = atts.getName(i); //-- skip namespace declarations if (attName.equals(XMLNS)) continue; String prefix = ""; idx = attName.indexOf(':'); if (idx >= 0) { prefix = attName.substring(0, idx); attName = attName.substring(idx+1); } if (prefix.equals(XMLNS)) continue; AttributeDecl attr = new AttributeDecl(_schema, attName); //-- guess simple type String typeName = _nsPrefix + ':' + DatatypeHandler.guessType(atts.getValue(i)); attr.setSimpleTypeReference(typeName); sInfo.attributes.addElement(attr); } } //-- startElement
/** * Merges the two element declarations. The resulting * merge is placed in ElementDecl e1. * * @param e1 the main ElementDecl * @param e2 the secondary ElementDecl to merge with e1 **/ private void merge(ElementDecl e1, ElementDecl e2) throws SchemaException { XMLType e1Type = e1.getType(); XMLType e2Type = e2.getType(); //-- Make sure types are not null and if so create them if (e1Type == null) { if (e2Type == null) return; //-- nothing to merge else { if (e2Type.isSimpleType()) { e1.setType(e2Type); } else { ComplexType cType = new ComplexType(_schema); Group group = new Group(); group.setOrder(_defaultGroupOrder); cType.addGroup(group); e1.setType(cType); e1Type = cType; } } } else if (e2Type == null) { if (e1Type.isSimpleType()) { e2.setType(e1Type); } else { ComplexType cType = new ComplexType(_schema); Group group = new Group(); group.setOrder(_defaultGroupOrder); cType.addGroup(group); e2.setType(cType); e2Type = cType; } } //-- both simple types if (e1Type.isSimpleType() && e2Type.isSimpleType()) { if (!e1Type.getName().equals(e2Type.getName())) { String typeName = _nsPrefix + ':' + DatatypeHandler.whichType(e1Type.getName(), e2Type.getName()); e1.setType(null); e1.setTypeReference(typeName); } return; } //-- e1 is simple, e2 is complex else if (e1Type.isSimpleType()) { ComplexType cType = new ComplexType(_schema); e1.setType(cType); Group group = new Group(); group.setOrder(_defaultGroupOrder); cType.addGroup(group); cType.setContentType(ContentType.mixed); e1Type = cType; //-- do not return here...we need to now treat as both //-- were complex } //-- e2 is simple, e1 is complex else if (e2Type.isSimpleType()) { ComplexType cType = new ComplexType(_schema); e2.setType(cType); Group group = new Group(); group.setOrder(_defaultGroupOrder); cType.addGroup(group); cType.setContentType(ContentType.mixed); e2Type = cType; //-- do not return here...we need to now treat as both //-- were complex } //-- both complex types ComplexType cType1 = (ComplexType)e1Type; ComplexType cType2 = (ComplexType)e2Type; //-- loop through all element/attribute declarations //-- of e2 and add them to e1 if they do not already exist //-- and mark them as optional Group e1Group = (Group) cType1.getParticle(0); if (e1Group == null) { e1Group = new Group(); e1Group.setOrder(_defaultGroupOrder); cType1.addGroup(e1Group); } Group e2Group = (Group) cType2.getParticle(0); if (e2Group == null) { e2Group = new Group(); e2Group.setOrder(_defaultGroupOrder); cType2.addGroup(e2Group); } Enumeration enum = e2Group.enumerate(); while (enum.hasMoreElements()) { Particle particle = (Particle)enum.nextElement(); if (particle.getStructureType() == Structure.ELEMENT) { ElementDecl element = (ElementDecl)particle; ElementDecl main = e1Group.getElementDecl(element.getName()); if (main == null) { e1Group.addElementDecl(element); element.setMinOccurs(0); } else { merge(main, element); } } } //-- add all attributes from type2 enum = cType2.getAttributeDecls(); while (enum.hasMoreElements()) { //-- check for attribute with same name AttributeDecl attNew = (AttributeDecl)enum.nextElement(); String attName = attNew.getName(); AttributeDecl attPrev = cType1.getAttributeDecl(attName); if (attPrev == null) { attNew.setUse(AttributeDecl.USE_OPTIONAL); cType1.addAttributeDecl(attNew); } else { String type1 = attPrev.getSimpleType().getName(); String type2 = attNew.getSimpleType().getName(); if (!type1.equals(type2)) { String typeName = _nsPrefix + ':' + DatatypeHandler.whichType(type1, type2); attPrev.setSimpleTypeReference(typeName); } } } //-- loop through all element/attribute declarations //-- of e1 and if they do not exist in e2, simply //-- mark them as optional enum = e1Group.enumerate(); while (enum.hasMoreElements()) { Particle particle = (Particle)enum.nextElement(); if (particle.getStructureType() == Structure.ELEMENT) { ElementDecl element = (ElementDecl)particle; if (e2Group.getElementDecl(element.getName()) == null) { element.setMinOccurs(0); } } } } //-- merge