diff --git a/xoai-service-provider/src/main/java/org/dspace/xoai/serviceprovider/parsers/MetadataParser.java b/xoai-service-provider/src/main/java/org/dspace/xoai/serviceprovider/parsers/MetadataParser.java index f4ef0d0a..f0c79582 100644 --- a/xoai-service-provider/src/main/java/org/dspace/xoai/serviceprovider/parsers/MetadataParser.java +++ b/xoai-service-provider/src/main/java/org/dspace/xoai/serviceprovider/parsers/MetadataParser.java @@ -8,21 +8,30 @@ package org.dspace.xoai.serviceprovider.parsers; -import com.lyncode.xml.XmlReader; -import com.lyncode.xml.exceptions.XmlReaderException; +import static com.lyncode.xml.matchers.QNameMatchers.localPart; +import static com.lyncode.xml.matchers.XmlEventMatchers.aStartElement; +import static com.lyncode.xml.matchers.XmlEventMatchers.anEndElement; +import static com.lyncode.xml.matchers.XmlEventMatchers.elementName; +import static com.lyncode.xml.matchers.XmlEventMatchers.text; +import static com.lyncode.xml.matchers.XmlEventMatchers.theEndOfDocument; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.AllOf.allOf; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.events.XMLEvent; + +import org.apache.commons.lang3.StringUtils; import org.dspace.xoai.model.xoai.Element; import org.dspace.xoai.model.xoai.Field; import org.dspace.xoai.model.xoai.XOAIMetadata; import org.hamcrest.Matcher; -import javax.xml.namespace.QName; -import javax.xml.stream.events.XMLEvent; -import java.io.InputStream; - -import static com.lyncode.xml.matchers.QNameMatchers.localPart; -import static com.lyncode.xml.matchers.XmlEventMatchers.*; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.core.AllOf.allOf; +import com.lyncode.xml.XmlReader; +import com.lyncode.xml.exceptions.XmlReaderException; public class MetadataParser { public XOAIMetadata parse(InputStream input) throws XmlReaderException { @@ -30,35 +39,53 @@ public XOAIMetadata parse(InputStream input) throws XmlReaderException { XmlReader reader = new XmlReader(input); reader.next(elementName(localPart(equalTo("metadata")))); - while (reader.next(theEndOfDocument(), anEndElement(), startElement()).current(startElement())) { - metadata.withElement(parseElement(reader)); - } - - return metadata; - } - - private Element parseElement(XmlReader reader) throws XmlReaderException { - Element element = new Element(reader.getAttributeValue(name())); - while (reader.next(startElement(), startField(), endOfMetadata()).current(startElement())) { - element.withElement(parseElement(reader)); + List elementsWithFields = new ArrayList(); + List elementName = new ArrayList(); + while (moreToGo(reader)) + { + //System.err.println("loop, now on " + reader.getName()); + if (reader.current(startElement())) + { + elementName.add(reader.getAttributeValue(name())); + //System.err.println(">> ."+reader.getAttributeValue(name())); + reader.next(startElement(), endElement(), startField(), endMetadata()); + } + if (reader.current(startField())) { + Element element = new Element(StringUtils.join(elementName, ".")); + while (reader.current(startField())) { + Field field = new Field() + .withName(reader.getAttributeValue(name())); + + if (reader.next(anEndElement(), text()).current(text())) + field.withValue(reader.getText()); + + element.withField(field); + //System.err.println("just added field " + field.getName() + " in " + element.getName()); + reader.next(startField(), startElement(), endElement()); + } + elementsWithFields.add(element); + //System.err.println("found e=" + element.getName()); + //System.err.println("now at " + reader.getName() + " " + reader.current(startElement()) + " " + reader.current(endElement())); + } + if (reader.current(endElement()) && elementName.size() > 0) { + elementName.remove(elementName.size() -1); + } } - - while (reader.current(startField())) { - Field field = new Field() - .withName(reader.getAttributeValue(name())); - - if (reader.next(anEndElement(), text()).current(text())) - field.withValue(reader.getText()); - - element.withField(field); - reader.next(startField(), endElement()); + for(Element e : elementsWithFields) + { + metadata.withElement(e); } - return element; + return metadata; } - - private Matcher startField() { - return allOf(aStartElement(), elementName(localPart(equalTo("field")))); + + private boolean moreToGo(XmlReader reader) throws XmlReaderException + { + if (reader.current(endMetadata())) + return false; + if (reader.current(startElement())) + return true; + return ! reader.next(startElement(), endElement(), startField(), endMetadata()).current(endMetadata()); } private Matcher endOfMetadata() { @@ -75,4 +102,7 @@ private Matcher startElement() { private Matcher endElement() { return allOf(anEndElement(), elementName(localPart(equalTo("element")))); } + private Matcher endMetadata() { + return allOf(anEndElement(), elementName(localPart(equalTo("metadata")))); + } }