From 36deaa6002a0e85d7da6efd7e569d91f976d9949 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 31 Dec 2015 16:08:16 +0000 Subject: Move XML parsing code into its own package --- .../org/zwobble/mammoth/xml/parsing/XmlParser.java | 81 ++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java (limited to 'src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java') diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java new file mode 100644 index 0000000..5354f07 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java @@ -0,0 +1,81 @@ +package org.zwobble.mammoth.xml.parsing; + +import java.io.InputStream; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Map; + +import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import org.zwobble.mammoth.xml.XmlElement; +import org.zwobble.mammoth.xml.XmlTextNode; + +import static java.util.stream.Collectors.toMap; + +public class XmlParser { + private final BiMap namespaces; + + public XmlParser(BiMap namespaces) { + this.namespaces = namespaces; + } + + public XmlElement parseStream(InputStream inputStream) { + NodeGenerator nodeGenerator = new NodeGenerator(); + SimpleSax.parseStream(inputStream, nodeGenerator); + return nodeGenerator.getRoot(); + } + + public XmlElement parseString(String value) { + NodeGenerator nodeGenerator = new NodeGenerator(); + SimpleSax.parseString(value, nodeGenerator); + return nodeGenerator.getRoot(); + } + + private class NodeGenerator implements SimpleSaxHandler { + private final Deque elementStack; + + public NodeGenerator() { + elementStack = new ArrayDeque<>(); + } + + public XmlElement getRoot() { + return elementStack.getFirst().build(); + } + + @Override + public void startElement(ElementName name, Map attributes) { + Map simpleAttributes = attributes + .entrySet() + .stream() + .collect(toMap( + entry -> readName(entry.getKey()), + entry -> entry.getValue())); + XmlElementBuilder element = new XmlElementBuilder(readName(name), simpleAttributes); + elementStack.add(element); + } + + private String readName(ElementName name) { + if (Strings.isNullOrEmpty(name.getUri())) { + return name.getLocalName(); + } else if (namespaces.containsValue(name.getUri())) { + return namespaces.inverse().get(name.getUri()) + ":" + name.getLocalName(); + } else { + return "{" + name.getUri() + "}" + name.getLocalName(); + } + + } + + @Override + public void endElement() { + if (elementStack.size() > 1) { + XmlElementBuilder element = elementStack.removeLast(); + elementStack.getLast().addChild(element.build()); + } + } + + @Override + public void characters(String string) { + elementStack.getLast().addChild(new XmlTextNode(string)); + } + } +} -- cgit v1.2.3