add: стабильная версия

This commit is contained in:
2024-02-27 14:20:49 +03:00
commit 38dd350d59
19 changed files with 749 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
package ru.di9.xml;
interface StringUtils {
static boolean isEmpty(String string) {
return string == null || string.isBlank() || string.isEmpty();
}
}

View File

@@ -0,0 +1,87 @@
package ru.di9.xml;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.w3c.dom.Element;
import java.util.*;
import java.util.stream.Collectors;
/**
* Враппер над {@link Element org.w3c.dom.Element}
*/
public class XmlElement implements Iterable<XmlElement> {
private final Element element;
public XmlElement(Element element) {
this.element = element;
}
public String getTagName() {
return element.getTagName();
}
public String getValue() {
return element.getTextContent();
}
public int getValueAsInt() {
var value = element.getTextContent();
return StringUtils.isEmpty(value) ? 0 : Integer.parseInt(value);
}
public float getValueAsFloat() {
var value = element.getTextContent();
return StringUtils.isEmpty(value) ? 0.0f : Float.parseFloat(value);
}
public boolean getValueAsBool() {
var value = element.getTextContent();
return !StringUtils.isEmpty(value) && Boolean.parseBoolean(value);
}
public List<String> getValueAsListString() {
var value = element.getTextContent();
return StringUtils.isEmpty(value) ? Collections.emptyList() : Arrays.asList(value.split(","));
}
public IntList getValueAsListInt() {
var value = element.getTextContent();
return StringUtils.isEmpty(value) ? IntList.of() : Arrays.stream(value.split(","))
.map(Integer::parseInt)
.collect(Collectors.toCollection(IntArrayList::new));
}
public boolean hasAttribute(String key) {
return element.hasAttribute(key);
}
public String getAttribute(String key) {
return element.getAttribute(key);
}
public int getAttributeAsInt(String key) {
var value = element.getAttribute(key);
return StringUtils.isEmpty(value) ? 0 : Integer.parseInt(value);
}
public boolean getAttributeAsBool(String key) {
var value = element.getAttribute(key);
return !StringUtils.isEmpty(value) && Boolean.parseBoolean(value);
}
@SuppressWarnings("NullableProblems")
@Override
public Iterator<XmlElement> iterator() {
return new XmlElementIterator(element.getChildNodes());
}
public Optional<XmlElement> getFirstElementByTagName(String tagName) {
var iterator = new XmlElementIterator(this.element.getElementsByTagName(tagName));
if (iterator.hasNext()) {
return Optional.of(iterator.next());
} else {
return Optional.empty();
}
}
}

View File

@@ -0,0 +1,42 @@
package ru.di9.xml;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.Iterator;
public class XmlElementIterator implements Iterator<XmlElement> {
private final NodeList nodeList;
private int index = 0;
private XmlElement next;
XmlElementIterator(NodeList nodeList) {
this.nodeList = nodeList;
}
@Override
public boolean hasNext() {
if (index >= nodeList.getLength()) {
next = null;
return false;
}
Node node;
do {
node = nodeList.item(index++);
} while (index < nodeList.getLength() && node.getNodeType() != Node.ELEMENT_NODE);
if (node.getNodeType() != Node.ELEMENT_NODE) {
next = null;
return false;
}
next = new XmlElement((org.w3c.dom.Element) node);
return true;
}
@Override
public XmlElement next() {
return next;
}
}

View File

@@ -0,0 +1,7 @@
package ru.di9.xml;
public class XmlException extends RuntimeException {
public XmlException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,69 @@
package ru.di9.xml;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
public class XmlParser {
private final DocumentBuilder documentBuilder;
public XmlParser() {
try {
this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new XmlException(e);
}
}
public XmlElement parse(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
return new XmlElement(documentBuilder.parse(inputStream).getDocumentElement());
} catch (SAXException | IOException e) {
throw new XmlException(e);
}
}
public XmlElement parse(File file) {
if (file == null) {
return null;
}
try {
return new XmlElement(documentBuilder.parse(file).getDocumentElement());
} catch (SAXException | IOException e) {
throw new XmlException(e);
}
}
public XmlElement parse(String xml) {
if (StringUtils.isEmpty(xml)) {
return null;
}
return parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
}
public Optional<XmlElement> parseOptional(InputStream inputStream) {
return Optional.ofNullable(parse(inputStream));
}
public Optional<XmlElement> parseOptional(File file) {
return Optional.ofNullable(parse(file));
}
public Optional<XmlElement> parseOptional(String xml) {
return Optional.ofNullable(parse(xml));
}
}