package main.expressions; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.ArrayList; import java.util.HashMap; import java.util.Stack; public class NodeContainer { /* Document: the root node of the XML document; Element: element nodes; Attribute: attribute nodes, represented as children of an Element node; (not a true parent child relationship) Text: text nodes, i.e., leaves of the XML tree. (always associated with an element node) */ /* Things to ask: Can it be assumed that an element node only has one text node (for the text func)? Format of input, a string or file of multiple xpath queries? -specify as a command line argument (string plus document) Milestone Deadline-Monday 2/6 */ public ArrayList validNodes; //all current valid nodes public ArrayList finalNodes; //all final nodes (collect constructed nodes) public HashMap> varBindings; public ArrayList attrList; //boolean slashRule; //not needed -> all cases require children nodes to be checked for tag-name Document rootDoc; //document node, present if every needed to be referred to NodeContainer(Document doc){ this.rootDoc = doc; this.validNodes = new ArrayList<>(); this.validNodes.add(doc); this.varBindings = new HashMap<>(); this.finalNodes = new ArrayList<>(); } NodeContainer(){ this.validNodes = new ArrayList<>(); this.varBindings = new HashMap<>(); this.finalNodes = new ArrayList<>(); this.rootDoc = null; } NodeContainer(NodeContainer nodeToCopy){ this.validNodes = nodeToCopy.validNodes; this.rootDoc = nodeToCopy.rootDoc; this.varBindings = nodeToCopy.varBindings; this.finalNodes = nodeToCopy.finalNodes; } void addOnlyChildren(){ if (validNodes.size() == 0){ return; } ArrayList allNodes = new ArrayList<>(); for (Node vNode: validNodes){ NodeList nl = vNode.getChildNodes(); for (int i = 0; i < nl.getLength(); i++){ if (nl.item(i).getNodeType() == Node.ELEMENT_NODE){ allNodes.add(nl.item(i)); } } } this.validNodes = allNodes; } void addElement(Node toAdd){ validNodes.add(toAdd); } // for the // operator, populates with all nodes in each subtree (where the root of each subtree // is the nodes currently in validNodes) void iterativeAddAll(){ if (validNodes.size() == 0){ return; } Stack nodeStack = new Stack<>(); ArrayList allNodes = new ArrayList<>(); NodeList toTraverse; for (Node vNode: validNodes){ nodeStack.push(vNode); while(!nodeStack.empty()) { allNodes.add(nodeStack.peek()); //collect node at visit toTraverse = nodeStack.peek().getChildNodes(); //get children nodeStack.pop(); //pop off stack when visit is complete for (int i = toTraverse.getLength() - 1; i >= 0; i--) { //push onto stack right to left //if (toTraverse.item(i).getNodeType() == Node.ELEMENT_NODE) { // nodeStack.push(toTraverse.item(i)); //} nodeStack.push(toTraverse.item(i)); } } nodeStack.clear(); } validNodes = allNodes; } void printElements(){ //for displaying elements int i = 1; for (Node n: validNodes){ System.out.println("Node Number " + i + " Node Name: " + n.getNodeName()); System.out.println(n.getTextContent()); System.out.println(); i++; } } }