Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /* ************************************************************************
   #
   #  DivConq
   #
   #  http://divconq.com/
   #
   #  Copyright:
   #    Copyright 2014 eTimeline, LLC. All rights reserved.
   #
  #  License:
  #    See the license.txt file in the project's top-level directory for details.
  #
  #  Authors:
  #    * Andy White
  #
  ************************************************************************ */
  package divconq.xml;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  
Represents a XML element and contains all the information that the original had. Attributes may be set, accessed and deleted. Child elements may be set accessed or deleted. This can be converted back to XML, along with its children, in a formatted or unformatted string.
  
  public class XElement extends XNode {
  	protected String tagName = null;
  	protected int line = 0;
  	protected int col = 0;
  
  	protected Map<StringStringattributes = null;
  	protected List<XNodechildren = null;
  	protected String comment = null;

constructor specifying the name with an optional array of objects to be added as child elements

Parameters:
tag the name of the tag
children an array of objects to be added as children
  
  	public XElement(String tagObject... children) {
  		this. = tag;
  
  		for (int i = 0; i < children.lengthi++) {
  			Object obj = children[i];
  
  			if (obj instanceof XNode)
  				this.add((XNodeobj);
  			else if (obj instanceof XAttribute)
  				this.setAttribute(((XAttributeobj).getName(), ((XAttributeobj).getRawValue());
  			else
  				this.add(obj.toString());
  		}
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see java.lang.Object#clone()
  	 */
  	/*
  	 * TODO public Object clone() throws CloneNotSupportedException {
  	 * TaggedElement newElement = (TaggedElement)super.clone(); if (attributes
  	 * != null) { newElement.attributes = new
  	 * HashMap<String,String>(attributes); } if (elements != null) {
  	 * newElement.elements = new ArrayList<Element>(); Iterator<Element> it =
  	 * elements.iterator(); while (it.hasNext()) {
  	 * newElement.elements.add((Element)it.next().clone()); } } return
  	 * newElement; }
  	 */
  
  	public XElement(XMLStreamReader xmlStreamReaderboolean keepwhitespace) {
  		this. = xmlStreamReader.getLocalName();
  		
  		 for (int a = 0; a < xmlStreamReader.getAttributeCount(); a++) 
  			 this.setAttribute(xmlStreamReader.getAttributeLocalName(a), xmlStreamReader.getAttributeValue(a));
  		
  		 try {
  			while (xmlStreamReader.hasNext()) {
  				 int n = xmlStreamReader.next();
  			        
  				 switch (n) {
 					 this.add(new XElement(xmlStreamReaderkeepwhitespace));					 
 					 break;
 					 return;
 					 String str = xmlStreamReader.getText();
 					 
 					if (!keepwhitespace) {
 						str = StringUtil.stripWhitespacePerXml(str);
 					}
 
 					// this is not always good - see if we can do it anyway
 					if (StringUtil.isEmpty(str)) 
 						break;
 					
 					XText text = new XText();
 					
 					text.setRawValue(str);
 					
 					this.add(text);
 						
 					 break;
 					 /*
 				 case XMLStreamConstants.ATTRIBUTE:
 					 for (int a = 0; a < xmlStreamReader.getAttributeCount(); a++) {
 						 this.setAttribute(xmlStreamReader.getAttributeLocalName(a), xmlStreamReader.getAttributeValue(a));
 					 }
 					 break;
 					 */
 					 String str2 = xmlStreamReader.getText();
 					 
 						if (!keepwhitespace) {
 							str2 = str2.trim();
 							
 							if (StringUtil.isEmpty(str2)) 
 								break;
 						}
 						
 						XText text2 = new XText();
 						
 						text2.setValue(str2true);
 						
 						this.add(text2);
 					 break;
 				 }
 			 }
 		} 
 		 catch (XMLStreamException x) {
 			// TODO Auto-generated catch block
 		}
 	}

gets the element name

Returns:
the element name
 
 	public String getName() {
 		return this.;
 	}

sets an attribute of this element

Parameters:
name the name of the attribute to be set
value the value of the attribute to be set
 
 	public void setAttribute(String nameString value) {
 		if (this. == null)
 			this. = new HashMap<StringString>();
 
 		this..put(name, XNode.quote(value));
 	}
 	
 	public void setRawAttribute(String nameString value) {
 		if (this. == null)
 			this. = new HashMap<StringString>();
 
 		this..put(namevalue);
 	}

gets the specified attribute of this element

Parameters:
name the name of the attribute to get
Returns:
the value of the attribute
 
 	public String getAttribute(String name) {
 		return (this. == null ? null : XNode.unquote(this..get(name)));
 	}
 
 	public String getRawAttribute(String name) {
 		//return (this.attributes == null ? null : XNode.unquote(this.attributes.get(name)));
 		return (this. == null ? null : this..get(name));
 	}

gets the specified attribute of this element but returns given default value if the attribute does not exist

Parameters:
name the name of the attribute to get
defaultValue the value to be returned if the attribute doesn't exist
Returns:
the value of the attribute
 
 	public String getAttribute(String nameString defaultValue) {
 		String result = this.getAttribute(name);
 		return result == null ? defaultValue : result;
 	}

finds out whether an attribute exists

Parameters:
name the name of the attribute to look for
Returns:
whether the attribute exists in this element
 
 	public boolean hasAttribute(String name) {
 		return this. == null ? false : this..containsKey(name);
 	}

finds out whether this element has any attributes

Returns:
whether this element has any attributes
 
 	public boolean hasAttributes() {
 		return this. != null && !this..isEmpty();
 	}

gets the attributes in the form of an indexed table

Returns:
the attribute table for this element
 
 	public Map<StringStringgetAttributes() {
 		if (this. == null)
 			this. = new HashMap<StringString>();
 
 		return this.;
 	}

removes the named attribute

Parameters:
name Name of attribute to remove
 
 	public void removeAttribute(String name) {
 		if (this. != null)
 			this..remove(name);
 	}

gets the number of child elements this element has

Returns:
the number of child elements this element has
 
 	public int children() {
 		return this. == null ? 0 : this..size();
 	}

finds out whether this element has any child elements

Returns:
whether this element has any child elements
 
 	public boolean hasChildren() {
 		return this.children() != 0;
 	}

removes the children from this element
 
 	public void clearChildren() {
 		if ( != null)
 	}

adds a child to the end of this element

Parameters:
element the child element to be added
 
 	public void add(XNode element) {
 		this.add(-1, element);
 	}

inserts a child into this element. If the index is out of range, the child is added at the end

Parameters:
index the location to insert the child
element the child element to be added
 
 	public void add(int indexXNode element) {
 		if (this. == null)
 			this. = new ArrayList<XNode>();
 
 		if ((index < 0) || (index >= this..size()))
 			this..add(element);
 		else
 			this..add(indexelement);
 	}

adds a child to the end of this element

Parameters:
string the child element to be added
 
 	public void add(String string) {
 		this.add(new XText(string));
 	}

inserts a child into this element If the index is out of range, the child is added at the end

Parameters:
index the location to insert the child
string the child element to be added
 
 	public void add(int indexString string) {
 		this.add(indexnew XText(string));
 	}

gets a child from the specified place in this element

Parameters:
i the index where the child is to be added
Returns:
the specified child
 
 	public XNode getChild(int i) {
 		if ((i < 0) || (i >= this.children()))
 			return null;
 
 		return this..get(i);
 	}

replaces a child element with the one given

Parameters:
index the child element number to replace
newElement the new element to replace the old one
 
 	public void replace(int indexXNode newElement) {
 		if (this. == null)
 			this. = new ArrayList<XNode>();
 		
 		if (index >= this..size())
 			this..add(newElement);
 		else
 			this..set(indexnewElement);
 	}

replaces all children with the children of the provided element

Parameters:
source the new element providing the source of the children
 
 	public void replaceChildren(XElement source) {
 		this. = new ArrayList<XNode>();
 
 		if (source.hasChildren())
 			this..addAll(source.children);
 	}
 	
 	public void replaceAttributes(XElement source) {
 		this. = new HashMap<StringString>();
 
 		if (source.hasAttributes()) 
 			this..putAll(source.attributes);
 	}
 	
 	public void replace(XElement source) {
 		this. = source.tagName;
 		this. = source.comment;
 		this.replaceChildren(source);
 		this.replaceAttributes(source);
 	}

Removes a child from this element

Parameters:
index the index of the child to be removed
Returns:
whether the child was found and removed or not
 
 	public XNode remove(int index) {
 		XNode result = null;
 		
 		if (this. == null)
 			this. = new ArrayList<XNode>();
 		
 		if (index >= 0 && index < this..size())
 			result = this..remove(index);
 		
 		return result;
 	}

Removes a child from this element

Parameters:
element the child to be removed
Returns:
whether the child was found and removed or not
 
 	public boolean remove(XNode element) {
 		if (element == null)
 			return true;
 		
 		return this..remove(element);
 	}

Finds a named child tagged element. If there is no such child, null is returned.

Parameters:
name the name of the child of this TaggedElement to find
Returns:
the name of the found element or null if not found
 
 	public XElement find(String... name) {
 		if (this. != null)
 			for (int i = 0; i < this..size(); i++) {
 				XNode element = this..get(i);
 				
 				if (element instanceof XElement) {
 					for (int n = 0; n < name.lengthn++)
 						if (((XElementelement).getName().equals(name[n]))
 							return (XElementelement;
 				}
 			}
 		
 		return null;
 	}
 
 	public XElement findId(String id) {
 		if (id == null)
 			return null;
 		
 		if (this. != null
 			if (id.equals(this.getAttribute("id")) || id.equals(this.getAttribute("Id")) || id.equals(this.getAttribute("ID")))
 				return this;
 		
 		if (this. != null) {
 			for (XNode n : this.) {
 				if (n instanceof XElement) {
 					XElement match = ((XElement)n).findId(id);
 					
 					if (match != null)
 						return match;
 				}
 			}
 		}
 		
 		return null;
 	}
 
 	public XElement findParentOfId(String id) {
 		return findParentOfId(idnull);
 	}
 
 	public XElement findParentOfId(String idXElement parent) {
 		if (id == null)
 			return null;
 		
 		if (this. != null
 			if (id.equals(this.getAttribute("id")) || id.equals(this.getAttribute("Id")) || id.equals(this.getAttribute("ID")))
 				return parent;
 		
 		if (this. != null) {
 			for (XNode n : this.) {
 				if (n instanceof XElement) {
 					XElement match = ((XElement)n).findParentOfId(idthis);
 					
 					if (match != null)
 						return match;
 				}
 			}
 		}
 		
 		return null;
 	}

A way to select child or sub child elements similar to XPath but lightweight. Cannot select values or attributes, just elements. * is supported to match all elements at a given level. For example: "Toys/Toy" called on "<Person>" means select all Toy elements inside of the Toys child element (child of Person). Cannot go up levels, or back to root. Do not start with a slash as in "/People".

Parameters:
path a backslash delimited string
Returns:
list of all matching elements, or empty list if no match
 
 	public List<XElementselectAll(String path) {
 		List<XElementmatches = new ArrayList<XElement>();
 		this.selectAll(pathmatches);
 		return matches;
 	}

Internal, recursive search used by selectAll

Parameters:
path a backslash delimited string
matches list of all matching elements, or empty list if no match
 
 	protected void selectAll(String pathList<XElementmatches) {
 		if (!this.hasChildren())
 			return;
 		
 		int pos = path.indexOf('/');
 
 		// go back to root not supported
 		if (pos == 0)
 			return;
 		
 		String name = null;
 		
 		if (pos == -1) {
 			name = path;
 			path = null;
 		}
 		else { 
 			name = path.substring(0, pos);
 			path = path.substring(pos + 1);
 		}
 		
 		// TODO add filter per XPath - [@n = f]
 		
 		for (XNode n : this.) {
 			if (n instanceof XElement) {
 				if ("*".equals(name) || ((XElement)n).getName().equals(name)) {
 					if (pos == -1) 
 						matches.add((XElement)n);
 					else  
 						((XElement)n).selectAll(pathmatches);
 				}
 			}
 		}
 	}

A way to select text of a child or sub child elements similar to XPath but lightweight. '*' is supported to match all elements at a given level. Returns only the first match. For example: "Toys/Toy" called on "<Person>" means return the text of first Toy element inside of the Toys child element (child of Person). Cannot go up levels, or back to root. Do not start with a slash as in "/People".

Parameters:
path a backslash delimited string
Returns:
text of first matching element, or null if no match
 
 	public String selectFirstText(String path) {
 		XElement first = this.selectFirst(path);
 		
 		if (first != null)
 			return first.getText();
 		
 		return null;
 	}

A way to select text of a child or sub child elements similar to XPath but lightweight. '*' is supported to match all elements at a given level. Returns only the first match. For example: "Toys/Toy" called on "<Person>" means return the text of first Toy element inside of the Toys child element (child of Person). Cannot go up levels, or back to root. Do not start with a slash as in "/People".

Parameters:
path a backslash delimited string
def default text if none found
Returns:
text of first matching element, or null if no match
 
 	public String selectFirstText(String pathString def) {
 		XElement first = this.selectFirst(path);
 		
 		if (first != null) {
 			String t = first.getText();
 			
 			if (StringUtil.isNotEmpty(t))
 				return t;
 		}
 		
 		return def;
 	}

A way to select text of a child or sub child elements similar to XPath but lightweight. '*' is supported to match all elements at a given level. Returns only the first match. For example: "Toys/Toy" called on "<Person>" means return the text of first Toy element inside of the Toys child element (child of Person). Cannot go up levels, or back to root. Do not start with a slash as in "/People".

Parameters:
path a backslash delimited string
def default object to return if path not found
Returns:
text of first matching element, or null if no match
 
 	public Object selectFirstValue(String pathObject def) {
 		XElement first = this.selectFirst(path);
 		
 		if (first != null) {
 			String t = first.getText();
 			
 			if (StringUtil.isNotEmpty(t))
 				return t;
 		}
 		
 		return def;
 	}

A way to select child or sub child elements similar to XPath but lightweight. Cannot select values or attributes, just elements. * is supported to match all elements at a given level. Returns only the first match. For example: "Toys/Toy" called on "<Person>" means return first Toy element inside of the Toys child element (child of Person). Cannot go up levels, or back to root. Do not start with a slash as in "/People".

Parameters:
path a backslash delimited string
Returns:
first matching element, or null if no match
 
 	public XElement selectFirst(String path) {
 		if (!this.hasChildren())
 			return null;
 		
 		int pos = path.indexOf('/');
 
 		// go back to root not supported
 		if (pos == 0)
 			return null;
 		
 		String name = null;
 		
 		if (pos == -1) {
 			name = path;
 			path = null;
 		}
 		else { 
 			name = path.substring(0, pos);
 			path = path.substring(pos + 1);
 		}
 		
 		// TODO add filter per XPath - [@n = f]
 		
 		for (XNode n : this.) {
 			if (n instanceof XElement) {
 				if ("*".equals(name) || ((XElement)n).getName().equals(name)) {
 					if (pos == -1) 
 						return (XElement)n;
 					else  {
 						XElement r = ((XElement)n).selectFirst(path);
 						
 						if (r != null)
 							return r;
 					}
 				}
 			}
 		}
 		
 		return null;
 	}

Finds the index of a named child tagged element. If there is no such child, -1 is returned.

Parameters:
name the name of the child of this TaggedElement to find
Returns:
the index of the found element or -1 if not found
 
 	public int findIndex(String name) {
 		if (this. != null)
 			for (int i = 0; i < this..size(); i++) {
 				XNode node = this..get(i);
 				
 				if (node instanceof XElement
 					if (((XElementnode).getName().equals(name))
 						return i;
 			}
 		
 		return -1;
 	}

sets the list of children of this element. This method replaces the current children.

Parameters:
elements the new list of children
 
 	public void setElements(List<XNodeelements) {
 		this. = elements;
 	}

gets a list of the children of this element. This method always returns a List even if it is empty.

Returns:
the List containing the children of this element
 
 	public Collection<XNodegetChildren() {
 		if (this. == null)
 			this. = new ArrayList<XNode>();
 		
 		return this.;
 	}

sets the XML source code location information for this element

Parameters:
line the line number of the start tag
col the column number of the start tag
 
 	public void setLocation(int lineint col) {
 		this. = line;
 		this. = col;
 	}

gets the XML source code line number where this element was declared. This number will be 0 if it was never set.

Returns:
the XML source code line number of this element's declaration
 
 	public int getLine() {
 		return this.;
 	}

gets the XML source code cloumn number where this element was declared. This number will be 0 if it was never set.

Returns:
the XML source code column number of this element's declaration
 
 	public int getCol() {
 		return this.;
 	}

get the comment associated with this element

Returns:
this element's comment
 
 	public String getComment() {
 		return this.;
 	}

set this element's comment

Parameters:
comment the comment to be stored
 
 	public void setComment(String comment) {
 		this. = comment;
 	}

Returns:
the text contained in this element if any, else null
 
 	public String getText() {
 		if (!this.hasChildren())
 			return null;
 		
 		// TODO improve to support multiple CDATA sections in one element
 		XNode f = this..get(0);
 		
 		if (f instanceof XText)
 			return ((XText)f).getValue();
 		
 		return null;
 	}
 
 	public boolean hasText() {
 		if (!this.hasChildren())
 			return false;
 		
 		// TODO improve to support multiple CDATA sections in one element
 		XNode f = this..get(0);
 		
 		if (f instanceof XText)
 			return true;
 		
 		return false;
 	}

assumes that the text content of this element is escaped xml, reads and parses the text content and returns the root element from that content

Parameters:
keepwhitespace don't strip white space when parsing the content of element
Returns:
root xml element for parsed content or null
 
 	public FuncResult<XElementtoXml(boolean keepwhitespace) {
 		if (!this.hasChildren()) {
 			res.errorTr(244);
 			return res;
 		}
 		
 		XNode f = this..get(0);
 		
 		if (f instanceof XText)
 			return XmlReader.parse(((XText)f).getValue(), keepwhitespace);
 		
 		res.errorTr(245);
 		return res;
 	}

assumes the text content of this element is Json, reads and parses the text content

Returns:
struct or null
 
 	public CompositeStruct toStruct() {
 		if (!this.hasChildren())
 			return null;
 		
 		XNode f = this..get(0);
 		
 		if (f instanceof XText)
 			return CompositeParser.parseJson(((XText)f).getValue()).getResult();
 		
 		return null;
 	}

Returns:
the first child node or null
 
 	public XNode getFirstChild() {
 		if (this.hasChildren())
 			return this..get(0);
 		
 		return null;
 	}
 
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see java.lang.Object#toString()
 	 */
 	public String toString() {
 		return this.toString(true);
 	}

returns just the tag start, not the content or children or the tag end. useful for debugging

Returns:
tag start in xml syntax
 
 	public String toLocalString() {
 		StringBuffer sb = new StringBuffer();
 
 		// Put the opening tag out
 		sb.append("<" + this.);
 
 		// Write the attributes out
 		if (this. != null
 			for (Map.Entry<StringStringentry : this..entrySet()) {
 				sb.append(" " + entry.getKey() + "=");
 				sb.append("\"" + entry.getValue() + "\"");
 			}
 
 		sb.append(">");
 		
 		return sb.toString();
 	}
 	
 	public String toInnerString() {
 		return this.toInnerString(true);
 	}
 	
 	public String toInnerString(boolean formatted) {
 	    StringBuffer sb = new StringBuffer();
 
 		// write out the closing tag or other elements
 		boolean formatThis = formatted;
 		
 		for (XNode element : this.) {
 			formatThis = (element instanceof XText) ? false : formatted;
 			element.toString(sbformatThis, 1);
 		}
 		
 	    return sb.toString();
 	}
 
 	/* (non-Javadoc)
 	 * @see divconq.xml.XNode#toString(java.lang.StringBuffer, boolean, int)
 	 */
 	protected StringBuffer toString(StringBuffer sbboolean formattedint level) {
 		// Add leading newline and spaces, if necessary
 		if (formatted && level > 0) {
 			sb.append("\n");
 			for (int i = leveli > 0; i--)
 				sb.append("\t");
 		}
 
 		// Put the opening tag out
 		sb.append("<" + this.);
 
 		// Write the attributes out
 		if (this. != null
 			for (Map.Entry<StringStringentry : this..entrySet()) {
 				sb.append(" " + entry.getKey() + "=");
 				sb.append("\"" + entry.getValue() + "\"");
 			}
 
 		// write out the closing tag or other elements
 		boolean formatThis = formatted;
 		boolean nontext = false;
 		
 		if (!this.hasChildren()) {
 			sb.append(" /> ");
 		} 
 		else {
 			sb.append(">");
 			
 			for (XNode node : this.) {
 				formatThis = (node instanceof XText) ? false : formatted;
 				
 				if (!(node instanceof XText))
 					nontext = true;
 
 				node.toString(sbformatThislevel + 1);
 			}
 			
 			// Add leading newline and spaces, if necessary
 			if (formatThis || nontext) {
 				sb.append("\n");
 				
 				for (int i = leveli > 0; i--)
 					sb.append("\t");
 			}
 			
 			// Now put the closing tag out
 			sb.append("</" + this. + "> ");
 		}
 		
 		return sb;
 	}
 	
 	/* (non-Javadoc)
 	 * @see divconq.xml.XNode#toMemory(divconq.lang.Memory, boolean, int)
 	 */
 	protected void toMemory(Memory sbboolean formattedint level) {
 		// Add leading newline and spaces, if necessary
 		if (formatted && level > 0) {
 			sb.write("\n");
 			for (int i = leveli > 0; i--)
 				sb.write("\t");
 		}
 
 		// Put the opening tag out
 		sb.write("<" + this.);
 
 		// Write the attributes out
 		if (this. != null
 			for (Map.Entry<StringStringentry : this..entrySet()) {
 				sb.write(" " + entry.getKey() + "=");
				sb.write("\"" + entry.getValue() + "\"");
		// write out the closing tag or other elements
		boolean formatThis = formatted;
		boolean nontext = false;
		if (!this.hasChildren()) {
			sb.write(" /> ");
		else {
			sb.write(">");
			for (XNode node : this.) {
				formatThis = (node instanceof XText) ? false : formatted;
				if (!(node instanceof XText))
					nontext = true;
				node.toMemory(sbformatThislevel + 1);
			// Add leading newline and spaces, if necessary
			if (formatThis || nontext) {
				sb.write("\n");
				for (int i = leveli > 0; i--)
					sb.write("\t");
			// Now put the closing tag out
			sb.write("</" + this. + "> ");
New to GrepCode? Check out our FAQ X