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

shz.core.xml.W3cXmlHelp Maven / Gradle / Ivy

package shz.core.xml;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import shz.core.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.regex.Pattern;

public final class W3cXmlHelp {
    private W3cXmlHelp() {
        throw new IllegalStateException();
    }

    public static Document getXmlDocument(InputSource in) {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            return db.parse(in);
        } catch (ParserConfigurationException | SAXException | IOException e) {
            throw PRException.of(e);
        }
    }

    public static Document getXmlDocument(String uri) {
        return getXmlDocument(new InputSource(uri));
    }

    public static Document getXmlDocument(File file) {
        return getXmlDocument(new InputSource(file.toURI().toASCIIString()));
    }

    public static Document getXmlDocument(InputStream is, String systemId) {
        InputSource in = new InputSource(is);
        in.setSystemId(systemId);
        return getXmlDocument(in);
    }

    public static Document getXmlDocument(InputStream is) {
        return getXmlDocument(new InputSource(is));
    }

    public static Document getXmlDocument(Reader reader) {
        return getXmlDocument(new InputSource(reader));
    }

    public static Node getXmlNode(Document document) {
        return document.getDocumentElement();
    }

    public static Map getNodeChildNodes(Node node) {
        NodeList nodelist = node.getChildNodes();
        if (nodelist.getLength() == 0) return Collections.emptyMap();
        Map map = ToMap.get(nodelist.getLength()).build();
        for (int i = 0; i < nodelist.getLength(); ++i)
            map.put(getKeyNum(nodelist.item(i).getNodeName(), 0), nodelist.item(i));
        return map.isEmpty() ? Collections.emptyMap() : map;
    }

    private static final String NAME_SEPARATOR = "--";
    private static final String NUM_SP = "N";

    private static String getKeyNum(String k, int num) {
        int len = k.length() - 5;
        int idx = k.indexOf(NUM_SP, Math.max(len, 0));
        idx = idx < 0 ? k.length() : idx;
        return k.substring(0, idx) + NUM_SP + num + NUM_SP;
    }

    public static Map getNodeAllChildNodes(Map map, String k, Node v, boolean pc) {
        NodeList nodelist = v.getChildNodes();
        if (nodelist.getLength() != 0) {
            if (pc) map.put(getKey(k, map, 0), v);
            for (int i = 0; i < nodelist.getLength(); ++i)
                getNodeAllChildNodes(map, getKey(k + NAME_SEPARATOR + nodelist.item(i).getNodeName(), map, 0), nodelist.item(i), pc);
        } else map.put(getKey(k, map, 0), v);
        return map.isEmpty() ? Collections.emptyMap() : map;
    }

    public static Map getNodeAllChildNodes(Map map, String k, Node v) {
        return getNodeAllChildNodes(map, k, v, false);
    }

    private static String getKey(String k, Map map, int num) {
        String keyNum = getKeyNum(k, num);
        return map.containsKey(keyNum) ? getKey(k, map, num + 1) : keyNum;
    }

    public static Map getXmlMap(Document document, boolean pc) {
        Map map = new HashMap<>();
        getNodeChildNodes(getXmlNode(document)).forEach((k, v) -> getNodeAllChildNodes(map, k, v, pc));
        return map.isEmpty() ? Collections.emptyMap() : map;
    }

    public static Map getXmlMap(Document document) {
        return getXmlMap(document, false);
    }

    public static Map getXmlMap(String uri, boolean pc) {
        return getXmlMap(getXmlDocument(uri), pc);
    }

    public static Map getXmlMap(String uri) {
        return getXmlMap(getXmlDocument(uri));
    }

    public static Map getXmlMap(File file, boolean pc) {
        return getXmlMap(getXmlDocument(file), pc);
    }

    public static Map getXmlMap(File file) {
        return getXmlMap(getXmlDocument(file));
    }

    private static final Pattern P_NUM = Pattern.compile(NUM_SP + "\\d+" + NUM_SP);

    public static List getXmlNodes(Map map, String names) {
        List result = new LinkedList<>();
        String[] allNames = names.trim().split(" +");
        String name = allNames[allNames.length - 1];
        String[] parentNames = new String[allNames.length - 1];
        System.arraycopy(allNames, 0, parentNames, 0, parentNames.length);
        int[] index = new int[parentNames.length];
        map.forEach((k, v) -> {
            String ps = RegexHelp.strip(k, P_NUM);
            if (ps.endsWith(name)) {
                if (parentNames.length == 0) result.add(v);
                else {
                    index[index.length - 1] = -1;
                    for (int i = 0; i < index.length; i++) if ((index[i] = ps.indexOf(parentNames[i])) == -1) break;
                    if (index[index.length - 1] != -1 && isMinToMax(index, 0)) result.add(v);
                }
            }
        });
        return result.isEmpty() ? Collections.emptyList() : result;
    }

    private static boolean isMinToMax(int[] index, int n) {
        if (n + 1 < index.length)
            if (index[n] < index[n + 1]) return isMinToMax(index, n + 1);
            else return false;
        return true;
    }

    public static List getXmlNodes(String xml, boolean pc, String name) {
        return getXmlNodes(getXmlMap(xml, pc), name);
    }

    static final class W3cXmlSetFieldStrategy extends BeanHelp.SetFieldStrategy {
        @Override
        public Function, Class, Collection>> supCollection() {
            return t -> (u, r) -> ToSet.collect(keys(t).stream().map(k -> executor(k, r)));
        }

        @Override
        public Function, Class[], Map>> supMap() {
            return t -> (u, r) -> ToMap.collect(keys(t).stream(), k -> executor(k, r[0]), k -> executor(k, r[1]));
        }

        @Override
        public Function, Class, Object>> supObject() {
            return t -> (u, r) -> executor(u.apply(t), r);
        }

        Map map;

        @Override
        protected Collection keys(Field field) {
            List keys = new ArrayList<>(map.size());
            String key = field.getName();
            int num = 0;
            String keyNum;
            while (map.containsKey(keyNum = getKeyNum(key, num))) {
                keys.add(keyNum);
                ++num;
            }
            return keys;
        }

        @Override
        protected Object executor(String key, Class cls) {
            return BeanHelp.of(cls, map, f -> key(key + NAME_SEPARATOR + f.getName()), n -> n == null ? null : ((Node) n).getTextContent(), this);
        }

        private String key(String key) {
            String keyNum = getKeyNum(key, 0);
            return map.containsKey(keyNum) ? keyNum : null;
        }

         T fromMap(Class cls, Map map) {
            this.map = map;
            return BeanHelp.of(cls, map, f -> key(f.getName()), n -> n == null ? null : ((Node) n).getTextContent(), this);
        }

         T fromMap(T t, Map map) {
            this.map = map;
            return BeanHelp.of(t, map, f -> key(f.getName()), n -> n == null ? null : ((Node) n).getTextContent(), this);
        }
    }

    private static final W3cXmlSetFieldStrategy STRATEGY = new W3cXmlSetFieldStrategy();

    public static  T toBean(Class cls, String uri) {
        return ((W3cXmlSetFieldStrategy) STRATEGY.clone()).fromMap(cls, getXmlMap(uri, true));
    }

    public static  T toBean(T t, String uri) {
        return ((W3cXmlSetFieldStrategy) STRATEGY.clone()).fromMap(t, getXmlMap(uri, true));
    }

    public static  T toBean(Class cls, File file) {
        return ((W3cXmlSetFieldStrategy) STRATEGY.clone()).fromMap(cls, getXmlMap(file, true));
    }

    public static  T toBean(T t, File file) {
        return ((W3cXmlSetFieldStrategy) STRATEGY.clone()).fromMap(t, getXmlMap(file, true));
    }

    public static String getValueFromXmlStrByKey(String xmlStr, String key) {
        if (NullHelp.isAnyBlank(xmlStr, key)) return null;
        return ((Element) getXmlNode(getXmlDocument(new StringReader(xmlStr)))).getElementsByTagName(key).item(0).getTextContent();
    }

    public static Map getValuesFromXmlStrByKeys(String xmlStr, String... keys) {
        if (NullHelp.isBlank(xmlStr) || NullHelp.isEmpty(keys)) return Collections.emptyMap();
        Element element = (Element) getXmlNode(getXmlDocument(new StringReader(xmlStr)));
        return ToMap.explicitCollect(Arrays.stream(keys), Function.identity(), k -> element.getElementsByTagName(k).item(0).getTextContent(), keys.length);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy