84 lines
2.5 KiB
Java
84 lines
2.5 KiB
Java
package com.github.dtschust.zork.parser.dom;
|
|
|
|
import com.github.dtschust.zork.parser.Property;
|
|
import org.w3c.dom.CharacterData;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.Node;
|
|
import org.w3c.dom.NodeList;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
public class DOMElement implements Property {
|
|
private final Element backing;
|
|
|
|
public DOMElement(final Element backing) {
|
|
this.backing = backing;
|
|
}
|
|
|
|
public static DOMElement of(final Element backing) {
|
|
return new DOMElement(backing);
|
|
}
|
|
|
|
/**
|
|
* Given a DOM element with one and only one child of text node type, returns the text as a string. If there is no
|
|
* such node, '?' is returned
|
|
* Get a string from an element (XML parsing stuff)
|
|
*
|
|
* @return the text as string, or '?'
|
|
*/
|
|
@Override
|
|
public String value() {
|
|
final Node child = backing.getFirstChild();
|
|
return child instanceof CharacterData ? ((CharacterData) child).getData() : "?";
|
|
}
|
|
|
|
@Override
|
|
public List<? extends Property> subPropertiesByName(final String name) {
|
|
return DOMElementList.byTagName(backing, name);
|
|
}
|
|
|
|
@Override
|
|
public String subPropertyValue(final String elementName,
|
|
final Optional<String> defaultValue) {
|
|
final NodeList field = backing.getElementsByTagName(elementName);
|
|
|
|
if (field.getLength() == 0) {
|
|
return defaultValue.orElseThrow(() ->
|
|
new IllegalArgumentException(elementName + " element count in container is not 1"));
|
|
}
|
|
|
|
final Node first = field.item(0);
|
|
if (!(first instanceof Element)) {
|
|
// the contract of getElementsByTagName states that it returns a list of Element objects
|
|
throw new IllegalStateException("unreachable");
|
|
}
|
|
|
|
return DOMElement.of((Element) first).value();
|
|
}
|
|
|
|
@Override
|
|
public String name() {
|
|
return backing.getTagName();
|
|
}
|
|
|
|
@Override
|
|
public boolean hasSubProperty(final String name) {
|
|
return backing.getElementsByTagName(name).getLength() > 0;
|
|
}
|
|
|
|
@Override
|
|
public List<Property> subProperties() {
|
|
final List<Property> elements = new ArrayList<>();
|
|
final NodeList children = backing.getChildNodes();
|
|
for (int i = 0; i < children.getLength(); i++) {
|
|
final Node item = children.item(i);
|
|
if (item instanceof Element) {
|
|
elements.add(DOMElement.of((Element) item));
|
|
}
|
|
}
|
|
return elements;
|
|
}
|
|
}
|