UPDATE updated to skip span and concat values ββfrom fields with the same name
Hello! I would suggest using a hash table to handle these "fields":
class XMLObject { private Hashtable mFields = new Hashtable(); private int mN = -1; public int getN() { return mN; } public void setN(int n) { mN = n; } public boolean isFieldExist(String key) { return mFields.containsKey(key); } public String getStringField(String key) { return (String) mFields.get(key); } public void setStringField(String key, String value) { mFields.put(key, value); } public String getPID() { return getStringField("PID"); } public void setPID(String pid) { setStringField("PID", pid); } public String getDcCoverage() { return getStringField("dc.coverage"); } public void setDcCoverage(String dcCoverage) { setStringField("dc.coverage", dcCoverage); } public String getFgsOwnerId() { return getStringField("fgs.ownerId"); } public void setFgsOwnerId(String fgsOwnerId) { setStringField("fgs.ownerId", fgsOwnerId); } public String dccreator() { return getStringField("dc.creator"); } public void dccreator(String dccreator) { setStringField("dc.creator", dccreator); } public String getdcformat() { return getStringField("dc.format"); } public void setdcformat(String dcformat) { setStringField("dc.format", dcformat); } public String getdcidentifier() { return getStringField("dc.identifier"); } public void setdcidentifier(String dcidentifier) { setStringField("dc.identifier", dcidentifier); } public String getdclanguage() { return getStringField("dc.language"); } public void setdclanguage(String dclanguage) { setStringField("dc.language", dclanguage); } public String getdcpublisher() { return getStringField("dc.publisher"); } public void setdcpublisher(String dcpublisher) { setStringField("dc.publisher", dcpublisher); } public String getdcsubject() { return getStringField("dc.subject"); } public void setdcsubject(String dcsubject) { setStringField("dc.subject", dcsubject); } public String getdctitle() { return getStringField("dc.title"); } public void setdctitle(String dctitle) { setStringField("dc.title", dctitle); } public String getdctype() { return getStringField("dc.type"); } public void setdctype(String dctype) { setStringField("dc.type", dctype); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("N:" + mN + ";"); Enumeration keys = mFields.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); sb.append(key + ":" + mFields.get(key) + ";\n"); } return sb.toString(); } }
Then, in the handler, you will not need to set any specific member of the class, just put the value using the "name" attribute as the key:
class XMLObjectHandler extends DefaultHandler { private String mCurrentTag = ""; private String mCurrentText = ""; private Attributes mCurrentAttr = null; private XMLObject[] mXMLObjects = new XMLObject[] {}; private XMLObject mCurrentXMLObject = new XMLObject(); private boolean mIgnoreTag = false; public XMLObject[] getXMLObjects() { return mXMLObjects; } public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { mIgnoreTag = mCurrentTag.equalsIgnoreCase("field") && name.equalsIgnoreCase("span"); if (!mIgnoreTag) { mCurrentTag = name; mCurrentAttr = attributes; } else { mCurrentText += " "; } if (mCurrentTag.equalsIgnoreCase("object")) { mCurrentXMLObject = new XMLObject(); mCurrentXMLObject.setN(Integer .parseInt(mCurrentAttr.getValue("no"))); } } public void characters(char[] ch, int start, int length) throws SAXException { if (mCurrentTag.equalsIgnoreCase("field")) mCurrentText = mCurrentText.concat(new String(ch, start, length)); } public void endElement(String uri, String localName, String name) throws SAXException { if (name.equalsIgnoreCase("field")) { String fieldName = mCurrentAttr.getValue("name"); if(mCurrentXMLObject.isFieldExist(fieldName)) { mCurrentText = mCurrentXMLObject.getStringField(fieldName) + " " + mCurrentText; } mCurrentXMLObject.setStringField(fieldName, mCurrentText); } else if (name.equalsIgnoreCase("object")) { Arrays.add(mXMLObjects, mCurrentXMLObject); } if (!mIgnoreTag) { mCurrentTag = ""; mCurrentText = ""; } else { mCurrentText += " "; } } }
See usage example:
public Scr() { StringBuffer sb = new StringBuffer(); sb.append("<Objects>"); sb.append("<Object no=\"1\">"); sb .append("<field name=\"PID\">ilives:87877</field>"+ "<field name=\"dc.coverage\">Charlottetown</field>"+ "<field name=\"fgs.ownerId\">fedoraAdmin</field>"); sb.append("</Object>"); sb.append("<Object no=\"2\">"); sb .append("<field name=\"PID\">ilives:87878</field>"+ "<field name=\"dc.coverage\">Rimston</field>"+ "<field name=\"fgs.ownerId\">jamesAdmin</field>"); sb.append("</Object>"); sb.append("</Objects>"); String xml = sb.toString(); ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); XMLObject[] xmlObjects = getXMLObjects(bais); for (int i = 0; i < xmlObjects.length; i++) { XMLObject o = xmlObjects[i]; add(new LabelField(o.toString())); } } static XMLObject[] getXMLObjects(InputStream is) { XMLObjectHandler xmlObjectHandler = new XMLObjectHandler(); try { SAXParser parser = SAXParserFactory.newInstance() .newSAXParser(); parser.parse(is, xmlObjectHandler); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return xmlObjectHandler.getXMLObjects(); } }
alt text http://img441.imageshack.us/img441/1372/saxj.jpg
PS If there are performance problems (for example, with more than 1000 xml objects), just replace the hash table with classes and the update processor, respectively ...