xmlparser.XmlIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simplexml Show documentation
Show all versions of simplexml Show documentation
A clean and simple XML parser, serializer, and deserializer.
package xmlparser;
import xmlparser.error.InvalidXml;
import xmlparser.model.XmlElement;
import xmlparser.utils.Escaping.UnEscape;
import xmlparser.utils.Interfaces.CheckedIterator;
import xmlparser.utils.Trimming.Trim;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import static xmlparser.utils.IO.newStreamReader;
public interface XmlIterator {
default CheckedIterator iterateXml(final InputStreamReader in) {
return new CheckedIterator() {
public boolean hasNext() throws IOException {
final Character next = readFirstNonWhiteChar(in);
if (next == null) return false;
if (next == '<') return true;
throw new InvalidXml();
}
public String next() throws IOException {
return readUntilCurrentTagIsClosed(in);
}
};
}
default CheckedIterator iterateDom(final InputStreamReader in, final Charset charset, final Trim trimmer, final UnEscape escaper) {
return new CheckedIterator() {
public boolean hasNext() throws Exception {
final Character next = readFirstNonWhiteChar(in);
if (next == null) return false;
if (next == '<') return true;
throw new InvalidXml();
}
public XmlElement next() throws Exception {
final String xml = readUntilCurrentTagIsClosed(in);
try (final InputStreamReader in = newStreamReader(xml, charset)) {
return XmlReader.toXmlDom(in, trimmer, escaper);
}
}
};
}
default CheckedIterator iterateObject(final InputStreamReader in, final Charset charset, final XmlReader reader
, final Class clazz, final Trim trimmer, final UnEscape escaper) {
return new CheckedIterator() {
public boolean hasNext() throws Exception {
final Character next = readFirstNonWhiteChar(in);
if (next == null) return false;
if (next == '<') return true;
throw new InvalidXml();
}
public T next() throws Exception {
final String xml = readUntilCurrentTagIsClosed(in);
try (final InputStreamReader in = newStreamReader(xml, charset)) {
final XmlElement element = XmlReader.toXmlDom(in, trimmer, escaper);
return reader.domToObject(element, clazz);
}
}
};
}
static Character readFirstNonWhiteChar(final InputStreamReader in) throws IOException {
int r;
while ((r = in.read()) != -1) {
final char c = (char) r;
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
return c;
}
return null;
}
static String readUntilCurrentTagIsClosed(final InputStreamReader in) throws IOException {
final StringBuilder builder = new StringBuilder();
builder.append('<');
boolean previousWasForwardSlash = false;
boolean previousWasSmallerThan = true;
int numberOfTagsOpened = 1;
int r;
while ((r = in.read()) != -1) {
final char c = (char) r;
builder.append(c);
if (c == '>' && previousWasForwardSlash) numberOfTagsOpened--;
if (c == '/' && previousWasSmallerThan) numberOfTagsOpened -= 2;
if (c == '<') numberOfTagsOpened++;
if (numberOfTagsOpened < 0) throw new InvalidXml();
if (numberOfTagsOpened == 0) {
if (c != '>') {
while ((r = in.read()) != -1) {
final char ch = (char) r;
builder.append(ch);
if (ch == '>') break;
}
}
break;
}
previousWasForwardSlash = c == '/';
previousWasSmallerThan = c == '<';
}
return builder.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy