All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xmlparser.XmlIterator Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
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