package Java;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import static org.w3c.dom.Node.ELEMENT_NODE;
import static org.w3c.dom.Node.TEXT_NODE;
/** @see org.w3c.dom.Node
*/
public final class Nodes {
private Nodes() {}
/** Whether `name` is the local name of `node`.
*
* @throws NullPointerException If either `name` or `node` is null.
*/
public static boolean hasName( final String name, final Node node ) {
return name.equals( node.getLocalName() ); }
/** Whether `node` is typed an an element.
*
* @see Node#getNodeType()
* @throws NullPointerException If `node` is null. Note the difference from the behaviour
* of the `instanceof` operator, which would instead return true.
*/
public static boolean isElement( final Node node ) { return node.getNodeType() == ELEMENT_NODE; }
/** Whether `node` is typed as text.
*
* @see Node#getNodeType()
* @throws NullPointerException If `node` is null. Note the difference from the behaviour
* of the `instanceof` operator, which would instead return true.
*/
public static boolean isText( final Node node ) { return node.getNodeType() == TEXT_NODE; }
/** Returns the nearest of the node’s subsequent siblings of the given local name,
* or null if there are none.
*/
public static Node nextSibling( Node node, final String name ) {
do node = node.getNextSibling(); while( node != null && !hasName( name, node ));
return node; }
/** Returns the parent of `node` as an element, or null if `node` has no parent.
*
* @throws ClassCastException If the parent of `node` is neither null nor an element.
*/
public static Element parentAsElement( final Node node ) { return (Element)node.getParentNode(); }
/** Returns the parent of `node` as an element; or null if `node` either has no parent,
* or its parent is not an element.
*/
public static Element parentElement( Node node ) {
node = node.getParentNode();
return node instanceof Element ? (Element)node : null; }
/** Returns the nearest of the node’s prior siblings of the given local name,
* or null if there are none.
*/
public static Node previousSibling( Node node, final String name ) {
do node = node.getPreviousSibling(); while( node != null && !hasName( name, node ));
return node; }
/** Returns the successor of `node` in document order, including any first child,
* or null if `node` has no successor.
*
* @see
* Definition of ‘document order’
*/
public static Node successor( final Node node ) {
Node s = node.getFirstChild();
if( s == null ) s = successorAfter( node );
return s; }
/** Returns the exclusive successor of `node` in document order, or null if there is none.
*
* @see
* Definition of ‘document order’
* @return The first successor of `node` outside of its descendants, or null if none exists.
*/
public static Node successorAfter( final Node node ) {
Node s = node.getNextSibling();
if( s == null ) {
final Node p = node.getParentNode();
if( p != null ) s = successorAfter( p ); }
return s; }
/** Returns the elemental successor of `n` in document order, including any first child,
* or null if `n` has no elemental successor.
*
* @see
* Definition of ‘document order’
*/
public static Element successorElement( Node n ) {
do n = successor( n ); while( n != null && !isElement(n) );
return (Element)n; }
/** Returns the exclusive elemental successor of `n` in document order, or null if there is none.
*
* @see
* Definition of ‘document order’
* @return The first elemental successor of `n` outside of its descendants,
* or null if none exists.
*/
public static Element successorElementAfter( Node n ) {
do n = successorAfter( n ); while( n != null && !isElement(n) );
return (Element)n; }
/** Returns the flat text (aka `data`) of the first child of the given node,
* which child must be a text node.
*/
public static String textChildFlat( final Node n ) { return ((Text)n.getFirstChild()).getData(); }}
// Copyright © 2022 Michael Allan. Licence MIT.