/* XMLElement.java NanoXML/Java
*
* This file is part of NanoXML 2 for Java.
* Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
* use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/
package processing.xml;
import java.io.*;
import java.util.*;
import processing.core.PApplet;
/**
* XMLElement is a representation of an XML object. The object is able to parse XML code. The methods described here are the most basic. More are documented in the Developer's Reference.
* <br><br>
* The encoding parameter inside XML files is ignored, only UTF-8 (or plain ASCII) are parsed properly.
* =advanced
* XMLElement is an XML element. This is the base class used for the
* Processing XML library, representing a single node of an XML tree.
*
* This code is based on a modified version of NanoXML by Marc De Scheemaecker.
*
* @author Marc De Scheemaecker
* @author processing.org
*
* @webref data:composite
* @usage Web & Application
* @instanceName xml any variable of type XMLElement
*/
public class XMLElement implements Serializable {
/**
* No line number defined.
*/
public static final int NO_LINE = -1;
/**
* The parent element.
*/
private XMLElement parent;
/**
* The attributes of the element.
*/
private Vector<XMLAttribute> attributes;
/**
* The child elements.
*/
private Vector<XMLElement> children;
/**
* The name of the element.
*/
private String name;
/**
* The full name of the element.
*/
private String fullName;
/**
* The namespace URI.
*/
private String namespace;
/**
* The content of the element.
*/
private String content;
/**
* The system ID of the source data where this element is located.
*/
private String systemID;
/**
* The line in the source data where this element starts.
*/
private int lineNr;
/**
* Creates an empty element to be used for #PCDATA content.
* @nowebref
*/
public XMLElement() {
this(null, null, null, NO_LINE);
}
protected void set(String fullName,
String namespace,
String systemID,
int lineNr) {
this.fullName = fullName;
if (namespace == null) {
this.name = fullName;
} else {
int index = fullName.indexOf(':');
if (index >= 0) {
this.name = fullName.substring(index + 1);
} else {
this.name = fullName;
}
}
this.namespace = namespace;
this.lineNr = lineNr;
this.systemID = systemID;
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
*/
// public XMLElement(String fullName) {
// this(fullName, null, null, NO_LINE);
// }
/**
* Creates an empty element.
*
* @param fullName the name of the element.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
// public XMLElement(String fullName,
// String systemID,
// int lineNr) {
// this(fullName, null, systemID, lineNr);
// }
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
*/
// public XMLElement(String fullName,
// String namespace) {
// this(fullName, namespace, null, NO_LINE);
// }
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
* @nowebref
*/
public XMLElement(String fullName,
String namespace,
String systemID,
int lineNr) {
this.attributes = new Vector<XMLAttribute>();
this.children = new Vector<XMLElement>(8);
this.fullName = fullName;
if (namespace == null) {
this.name = fullName;
} else {
int index = fullName.indexOf(':');
if (index >= 0) {
this.name = fullName.substring(index + 1);
} else {
this.name = fullName;
}
}
this.namespace = namespace;
this.content = null;
this.lineNr = lineNr;
this.systemID = systemID;
this.parent = null;
}
/**
* Begin parsing XML data passed in from a PApplet. This code
* wraps exception handling, for more advanced exception handling,
* use the constructor that takes a Reader or InputStream.
* @author processing.org
* @param filename name of the XML file to load
* @param parent typically use "this"
*/
public XMLElement(PApplet parent, String filename) {
this();
parseFromReader(parent.createReader(filename));
}
/**
* @nowebref
*/
public XMLElement(Reader r) {
this();
parseFromReader(r);
}
/**
* @nowebref
*/
public XMLElement(String xml) {
this();
parseFromReader(new StringReader(xml));
}
protected void parseFromReader(Reader r) {
try {
StdXMLParser parser = new StdXMLParser();
parser.setBuilder(new StdXMLBuilder(this));
parser.setValidator(new XMLValidator());
parser.setReader(new StdXMLReader(r));
//System.out.println(parser.parse().getName());
/*XMLElement xm = (XMLElement)*/ parser.parse();
//System.out.println("xm name is " + xm.getName());
//System.out.println(xm + " " + this);
//parser.parse();
} catch (XMLException e) {
e.printStackTrace();
}
}
// static public XMLElement parse(Reader r) {
// try {
// StdXMLParser parser = new StdXMLParser();
// parser.setBuilder(new StdXMLBuilder());
// parser.setValidator(new XMLValidator());
// parser.setReader(new StdXMLReader(r));
// return (XMLElement) parser.parse();
// } catch (XMLException e) {
// e.printStackTrace();
// return null;
// }
// }
/**
* Creates an element to be used for #PCDATA content.
*/
public XMLElement createPCDataElement() {
return new XMLElement();
}
/**
* Creates an empty element.
*
* @param fullName the name of the element.
*/
// public XMLElement createElement(String fullName) {
// return new XMLElement(fullName);
// }
/**
* Creates an empty element.
*
* @param fullName the name of the element.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
// public XMLElement createElement(String fullName,
// String systemID,
// int lineNr) {
// //return new XMLElement(fullName, systemID, lineNr);
// return new XMLElement(fullName, null, systemID, lineNr);
// }
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
*/
public XMLElement createElement(String fullName,
String namespace) {
//return new XMLElement(fullName, namespace);
return new XMLElement(fullName, namespace, null, NO_LINE);
}
/**
* Creates an empty element.
*
* @param fullName the full name of the element
* @param namespace the namespace URI.
* @param systemID the system ID of the XML data where the element starts.
* @param lineNr the line in the XML data where the element starts.
*/
public XMLElement createElement(String fullName,
String namespace,
String systemID,
int lineNr) {
return new XMLElement(fullName, namespace, systemID, lineNr);
}
/**
* Cleans up the object when it's destroyed.
*/
protected void finalize() throws Throwable {
this.attributes.clear();
this.attributes = null;
this.children = null;
this.fullName = null;
this.name = null;
this.namespace = null;
this.content = null;
this.systemID = null;
this.parent = null;
super.finalize();
}
/**
* Returns the parent element. This method returns null for the root
* element.
*/
public XMLElement getParent() {
return this.parent;
}
/**
* Returns the full name (i.e. the name including an eventual namespace
* prefix) of the element.
*
* @webref
* @brief Returns the name of the element.
* @return the name, or null if the element only contains #PCDATA.
*/
public String getName() {
return this.fullName;
}
/**
* Returns the name of the element.
*
* @return the name, or null if the element only contains #PCDATA.
*/
public String getLocalName() {
return this.name;
}
/**
* Returns the namespace of the element.
*
* @return the namespace, or null if no namespace is associated with the
* element.
*/
public String getNamespace() {
return this.namespace;
}
/**
* Sets the full name. This method also sets the short name and clears the
* namespace URI.
*
* @param name the non-null name.
*/
public void setName(String name) {
this.name = name;
this.fullName = name;
this.namespace = null;
}
/**
* Sets the name.
*
* @param fullName the non-null full name.
* @param namespace the namespace URI, which may be null.
*/
public void setName(String fullName, String namespace) {
int index = fullName.indexOf(':');
if ((namespace == null) || (index < 0)) {
this.name = fullName;
} else {
this.name = fullName.substring(index + 1);
}
this.fullName = fullName;
this.namespace = namespace;
}
/**
* Adds a child element.
*
* @param child the non-null child to add.
*/
public void addChild(XMLElement child) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
if ((child.getLocalName() == null) && (! this.children.isEmpty())) {
XMLElement lastChild = (XMLElement) this.children.lastElement();
if (lastChild.getLocalName() == null) {
lastChild.setContent(lastChild.getContent()
+ child.getContent());
return;
}
}
((XMLElement)child).parent = this;
this.children.addElement(child);
}
/**
* Inserts a child element.
*
* @param child the non-null child to add.
* @param index where to put the child.
*/
public void insertChild(XMLElement child, int index) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
if ((child.getLocalName() == null) && (! this.children.isEmpty())) {
XMLElement lastChild = (XMLElement) this.children.lastElement();
if (lastChild.getLocalName() == null) {
lastChild.setContent(lastChild.getContent()
+ child.getContent());
return;
}
}
((XMLElement) child).parent = this;
this.children.insertElementAt(child, index);
}
/**
* Removes a child element.
*
* @param child the non-null child to remove.
*/
public void removeChild(XMLElement child) {
if (child == null) {
throw new IllegalArgumentException("child must not be null");
}
this.children.removeElement(child);
}
/**
* Removes the child located at a certain index.
*
* @param index the index of the child, where the first child has index 0.
*/
public void removeChildAtIndex(int index) {
this.children.removeElementAt(index);
}
/**
* Returns an enumeration of all child elements.
*
* @return the non-null enumeration
*/
public Enumeration<XMLElement> enumerateChildren() {
return this.children.elements();
}
/**
* Returns whether the element is a leaf element.
*
* @return true if the element has no children.
*/
public boolean isLeaf() {
return this.children.isEmpty();
}
/**
* Returns whether the element has children.
*
* @return true if the element has children.
*/
public boolean hasChildren() {
return (! this.children.isEmpty());
}
/**
* Returns the number of children for the element.
*
* @return the count.
* @webref
* @see processing.xml.XMLElement#getChild(int)
* @see processing.xml.XMLElement#getChildren(String)
*/
public int getChildCount() {
return this.children.size();
}
/**
* Returns a vector containing all the child elements.
*
* @return the vector.
*/
// public Vector getChildren() {
// return this.children;
// }
/**
* Put the names of all children into an array. Same as looping through
* each child and calling getName() on each XMLElement.
*/
public String[] listChildren() {
int childCount = getChildCount();
String[] outgoing = new String[childCount];
for (int i = 0; i < childCount; i++) {
outgoing[i] = getChild(i).getName();
}
return outgoing;
}
/**
* Returns an array containing all the child elements.
*/
public XMLElement[] getChildren() {
int childCount = getChildCount();
XMLElement[] kids = new XMLElement[childCount];
children.copyInto(kids);
return kids;
}
/**
* Quick accessor for an element at a particular index.
* @author processing.org
* @param index the element
*/
public XMLElement getChild(int index) {
return (XMLElement) children.elementAt(index);
}
/**
* Returns the child XMLElement as specified by the <b>index</b> parameter. The value of the <b>index</b> parameter must be less than the total number of children to avoid going out of the array storing the child elements.
* When the <b>path</b> parameter is specified, then it will return all children that match that path. The path is a series of elements and sub-elements, separated by slashes.
*
* @return the element
* @author processing.org
*
* @webref
* @see processing.xml.XMLElement#getChildCount()
* @see processing.xml.XMLElement#getChildren(String)
* @brief Get a child by its name or path.
* @param path path to a particular element
*/
public XMLElement getChild(String path) {
if (path.indexOf('/') != -1) {
return getChildRecursive(PApplet.split(path, '/'), 0);
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
XMLElement kid = getChild(i);
String kidName = kid.getName();
if (kidName != null && kidName.equals(path)) {
return kid;
}
}
return null;
}
/**
* Internal helper function for getChild(String).
* @param items result of splitting the query on slashes
* @param offset where in the items[] array we're currently looking
* @return matching element or null if no match
* @author processing.org
*/
protected XMLElement getChildRecursive(String[] items, int offset) {
// if it's a number, do an index instead
if (Character.isDigit(items[offset].charAt(0))) {
XMLElement kid = getChild(Integer.parseInt(items[offset]));
if (offset == items.length-1) {
return kid;
} else {
return kid.getChildRecursive(items, offset+1);
}
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
XMLElement kid = getChild(i);
String kidName = kid.getName();
if (kidName != null && kidName.equals(items[offset])) {
if (offset == items.length-1) {
return kid;
} else {
return kid.getChildRecursive(items, offset+1);
}
}
}
return null;
}
/**
* Returns the child at a specific index.
*
* @param index the index of the child
*
* @return the non-null child
*
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds.
*/
public XMLElement getChildAtIndex(int index)
throws ArrayIndexOutOfBoundsException {
return (XMLElement) this.children.elementAt(index);
}
/**
* Searches a child element.
*
* @param name the full name of the child to search for.
*
* @return the child element, or null if no such child was found.
*/
// public XMLElement getFirstChildNamed(String name) {
// Enumeration enum = this.children.elements();
// while (enum.hasMoreElements()) {
// XMLElement child = (XMLElement) enum.nextElement();
// String childName = child.getFullName();
// if ((childName != null) && childName.equals(name)) {
// return child;
// }
// }
// return null;
// }
/**
* Searches a child element.
*
* @param name the name of the child to search for.
* @param namespace the namespace, which may be null.
*
* @return the child element, or null if no such child was found.
*/
// public XMLElement getFirstChildNamed(String name,
// String namespace) {
// Enumeration enum = this.children.elements();
// while (enum.hasMoreElements()) {
// XMLElement child = (XMLElement) enum.nextElement();
// String str = child.getName();
// boolean found = (str != null) && (str.equals(name));
// str = child.getNamespace();
// if (str == null) {
// found &= (name == null);
// } else {
// found &= str.equals(namespace);
// }
// if (found) {
// return child;
// }
// }
// return null;
// }
/**
* Returns all of the children as an XMLElement array.
* When the <b>path</b> parameter is specified, then it will return all children that match that path.
* The path is a series of elements and sub-elements, separated by slashes.
*
* @param path element name or path/to/element
* @return array of child elements that match
* @author processing.org
*
* @webref
* @brief Returns all of the children as an XMLElement array.
* @see processing.xml.XMLElement#getChildCount()
* @see processing.xml.XMLElement#getChild(int)
*/
public XMLElement[] getChildren(String path) {
if (path.indexOf('/') != -1) {
return getChildrenRecursive(PApplet.split(path, '/'), 0);
}
// if it's a number, do an index instead
// (returns a single element array, since this will be a single match
if (Character.isDigit(path.charAt(0))) {
return new XMLElement[] { getChild(Integer.parseInt(path)) };
}
int childCount = getChildCount();
XMLElement[] matches = new XMLElement[childCount];
int matchCount = 0;
for (int i = 0; i < childCount; i++) {
XMLElement kid = getChild(i);
String kidName = kid.getName();
if (kidName != null && kidName.equals(path)) {
matches[matchCount++] = kid;
}
}
return (XMLElement[]) PApplet.subset(matches, 0, matchCount);
}
protected XMLElement[] getChildrenRecursive(String[] items, int offset) {
if (offset == items.length-1) {
return getChildren(items[offset]);
}
XMLElement[] matches = getChildren(items[offset]);
XMLElement[] outgoing = new XMLElement[0];
for (int i = 0; i < matches.length; i++) {
XMLElement[] kidMatches = matches[i].getChildrenRecursive(items, offset+1);
outgoing = (XMLElement[]) PApplet.concat(outgoing, kidMatches);
}
return outgoing;
}
/**
* Returns a vector of all child elements named <I>name</I>.
*
* @param name the full name of the children to search for.
*
* @return the non-null vector of child elements.
*/
// public Vector getChildrenNamed(String name) {
// Vector result = new Vector(this.children.size());
// Enumeration enum = this.children.elements();
// while (enum.hasMoreElements()) {
// XMLElement child = (XMLElement) enum.nextElement();
// String childName = child.getFullName();
// if ((childName != null) && childName.equals(name)) {
// result.addElement(child);
// }
// }
// return result;
// }
/**
* Returns a vector of all child elements named <I>name</I>.
*
* @param name the name of the children to search for.
* @param namespace the namespace, which may be null.
*
* @return the non-null vector of child elements.
*/
// public Vector getChildrenNamed(String name,
// String namespace) {
// Vector result = new Vector(this.children.size());
// Enumeration enum = this.children.elements();
// while (enum.hasMoreElements()) {
// XMLElement child = (XMLElement) enum.nextElement();
// String str = child.getName();
// boolean found = (str != null) && (str.equals(name));
// str = child.getNamespace();
// if (str == null) {
// found &= (name == null);
// } else {
// found &= str.equals(namespace);
// }
//
// if (found) {
// result.addElement(child);
// }
// }
// return result;
// }
/**
* Searches an attribute.
*
* @param fullName the non-null full name of the attribute.
*
* @return the attribute, or null if the attribute does not exist.
*/
private XMLAttribute findAttribute(String fullName) {
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
if (attr.getFullName().equals(fullName)) {
return attr;
}
}
return null;
}
/**
* Searches an attribute.
*
* @param name the non-null short name of the attribute.
* @param namespace the name space, which may be null.
*
* @return the attribute, or null if the attribute does not exist.
*/
private XMLAttribute findAttribute(String name,
String namespace) {
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
boolean found = attr.getName().equals(name);
if (namespace == null) {
found &= (attr.getNamespace() == null);
} else {
found &= namespace.equals(attr.getNamespace());
}
if (found) {
return attr;
}
}
return null;
}
/**
* Returns the number of attributes.
*/
public int getAttributeCount() {
return this.attributes.size();
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
*
* @return the value, or null if the attribute does not exist.
*/
public String getAttribute(String name) {
return this.getAttribute(name, null);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null full name of the attribute.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public String getAttribute(String name,
String defaultValue) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return defaultValue;
} else {
return attr.getValue();
}
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public String getAttribute(String name,
String namespace,
String defaultValue) {
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
return defaultValue;
} else {
return attr.getValue();
}
}
public String getStringAttribute(String name) {
return getAttribute(name);
}
/**
* Returns a String attribute of the element.
* If the <b>default</b> parameter is used and the attribute doesn't exist, the <b>default</b> value is returned.
* When using the version of the method without the <b>default</b> parameter, if the attribute doesn't exist, the value 0 is returned.
*
* @webref
* @param name the name of the attribute
* @param default Value value returned if the attribute is not found
*
* @brief Returns a String attribute of the element.
*/
public String getStringAttribute(String name, String defaultValue) {
return getAttribute(name, defaultValue);
}
public String getStringAttribute(String name,
String namespace,
String defaultValue) {
return getAttribute(name, namespace, defaultValue);
}
/**
* Returns an integer attribute of the element.
*/
public int getIntAttribute(String name) {
return getIntAttribute(name, 0);
}
/**
* Returns an integer attribute of the element.
* If the <b>default</b> parameter is used and the attribute doesn't exist, the <b>default</b> value is returned.
* When using the version of the method without the <b>default</b> parameter, if the attribute doesn't exist, the value 0 is returned.
*
* @param name the name of the attribute
* @param defaultValue value returned if the attribute is not found
*
* @webref
* @brief Returns an integer attribute of the element.
* @return the value, or defaultValue if the attribute does not exist.
*/
public int getIntAttribute(String name,
int defaultValue) {
String value = this.getAttribute(name, Integer.toString(defaultValue));
return Integer.parseInt(value);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public int getIntAttribute(String name,
String namespace,
int defaultValue) {
String value = this.getAttribute(name, namespace,
Integer.toString(defaultValue));
return Integer.parseInt(value);
}
public float getFloatAttribute(String name) {
return getFloatAttribute(name, 0);
}
/**
* Returns a float attribute of the element.
* If the <b>default</b> parameter is used and the attribute doesn't exist, the <b>default</b> value is returned.
* When using the version of the method without the <b>default</b> parameter, if the attribute doesn't exist, the value 0 is returned.
*
* @param name the name of the attribute
* @param defaultValue value returned if the attribute is not found
*
* @return the value, or defaultValue if the attribute does not exist.
*
* @webref
* @brief Returns a float attribute of the element.
*/
public float getFloatAttribute(String name,
float defaultValue) {
String value = this.getAttribute(name, Float.toString(defaultValue));
return Float.parseFloat(value);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
* @nowebref
*/
public float getFloatAttribute(String name,
String namespace,
float defaultValue) {
String value = this.getAttribute(name, namespace,
Float.toString(defaultValue));
return Float.parseFloat(value);
}
public double getDoubleAttribute(String name) {
return getDoubleAttribute(name, 0);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null full name of the attribute.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public double getDoubleAttribute(String name,
double defaultValue) {
String value = this.getAttribute(name, Double.toString(defaultValue));
return Double.parseDouble(value);
}
/**
* Returns the value of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
* @param defaultValue the default value of the attribute.
*
* @return the value, or defaultValue if the attribute does not exist.
*/
public double getDoubleAttribute(String name,
String namespace,
double defaultValue) {
String value = this.getAttribute(name, namespace,
Double.toString(defaultValue));
return Double.parseDouble(value);
}
/**
* Returns the type of an attribute.
*
* @param name the non-null full name of the attribute.
*
* @return the type, or null if the attribute does not exist.
*/
public String getAttributeType(String name) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return null;
} else {
return attr.getType();
}
}
/**
* Returns the namespace of an attribute.
*
* @param name the non-null full name of the attribute.
*
* @return the namespace, or null if there is none associated.
*/
public String getAttributeNamespace(String name) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
return null;
} else {
return attr.getNamespace();
}
}
/**
* Returns the type of an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI, which may be null.
*
* @return the type, or null if the attribute does not exist.
*/
public String getAttributeType(String name,
String namespace) {
XMLAttribute attr = this.findAttribute(name, namespace);
if (attr == null) {
return null;
} else {
return attr.getType();
}
}
/**
* Sets an attribute.
*
* @param name the non-null full name of the attribute.
* @param value the non-null value of the attribute.
*/
public void setAttribute(String name,
String value) {
XMLAttribute attr = this.findAttribute(name);
if (attr == null) {
attr = new XMLAttribute(name, name, null, value, "CDATA");
this.attributes.addElement(attr);
} else {
attr.setValue(value);
}
}
/**
* Sets an attribute.
*
* @param fullName the non-null full name of the attribute.
* @param namespace the namespace URI of the attribute, which may be null.
* @param value the non-null value of the attribute.
*/
public void setAttribute(String fullName,
String namespace,
String value) {
int index = fullName.indexOf(':');
String vorname = fullName.substring(index + 1);
XMLAttribute attr = this.findAttribute(vorname, namespace);
if (attr == null) {
attr = new XMLAttribute(fullName, vorname, namespace, value, "CDATA");
this.attributes.addElement(attr);
} else {
attr.setValue(value);
}
}
/**
* Removes an attribute.
*
* @param name the non-null name of the attribute.
*/
public void removeAttribute(String name) {
for (int i = 0; i < this.attributes.size(); i++) {
XMLAttribute attr = (XMLAttribute) this.attributes.elementAt(i);
if (attr.getFullName().equals(name)) {
this.attributes.removeElementAt(i);
return;
}
}
}
/**
* Removes an attribute.
*
* @param name the non-null name of the attribute.
* @param namespace the namespace URI of the attribute, which may be null.
*/
public void removeAttribute(String name,
String namespace) {
for (int i = 0; i < this.attributes.size(); i++) {
XMLAttribute attr = (XMLAttribute) this.attributes.elementAt(i);
boolean found = attr.getName().equals(name);
if (namespace == null) {
found &= (attr.getNamespace() == null);
} else {
found &= attr.getNamespace().equals(namespace);
}
if (found) {
this.attributes.removeElementAt(i);
return;
}
}
}
/**
* Returns an enumeration of all attribute names.
*
* @return the non-null enumeration.
*/
public Enumeration<String> enumerateAttributeNames() {
Vector<String> result = new Vector<String>();
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
result.addElement(attr.getFullName());
}
return result.elements();
}
/**
* Returns whether an attribute exists.
*
* @return true if the attribute exists.
*/
public boolean hasAttribute(String name) {
return this.findAttribute(name) != null;
}
/**
* Returns whether an attribute exists.
*
* @return true if the attribute exists.
*/
public boolean hasAttribute(String name,
String namespace) {
return this.findAttribute(name, namespace) != null;
}
/**
* Returns all attributes as a Properties object.
*
* @return the non-null set.
*/
public Properties getAttributes() {
Properties result = new Properties();
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
result.put(attr.getFullName(), attr.getValue());
}
return result;
}
/**
* Returns all attributes in a specific namespace as a Properties object.
*
* @param namespace the namespace URI of the attributes, which may be null.
*
* @return the non-null set.
*/
public Properties getAttributesInNamespace(String namespace) {
Properties result = new Properties();
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
if (namespace == null) {
if (attr.getNamespace() == null) {
result.put(attr.getName(), attr.getValue());
}
} else {
if (namespace.equals(attr.getNamespace())) {
result.put(attr.getName(), attr.getValue());
}
}
}
return result;
}
/**
* Returns the system ID of the data where the element started.
*
* @return the system ID, or null if unknown.
*
* @see #getLineNr
*/
public String getSystemID() {
return this.systemID;
}
/**
* Returns the line number in the data where the element started.
*
* @return the line number, or NO_LINE if unknown.
*
* @see #NO_LINE
* @see #getSystemID
*/
public int getLineNr() {
return this.lineNr;
}
/**
* Returns the content of an element. If there is no such content, <b>null</b> is returned.
* =advanced
* Return the #PCDATA content of the element. If the element has a
* combination of #PCDATA content and child elements, the #PCDATA
* sections can be retrieved as unnamed child objects. In this case,
* this method returns null.
*
* @webref
* @brief Returns the content of an element
* @return the content.
*/
public String getContent() {
return this.content;
}
/**
* Sets the #PCDATA content. It is an error to call this method with a
* non-null value if there are child objects.
*
* @param content the (possibly null) content.
*/
public void setContent(String content) {
this.content = content;
}
/**
* Returns true if the element equals another element.
*
* @param rawElement the element to compare to
*/
public boolean equals(Object rawElement) {
try {
return this.equalsXMLElement((XMLElement) rawElement);
} catch (ClassCastException e) {
return false;
}
}
/**
* Returns true if the element equals another element.
*
* @param rawElement the element to compare to
*/
public boolean equalsXMLElement(XMLElement rawElement) {
if (! this.name.equals(rawElement.getLocalName())) {
return false;
}
if (this.attributes.size() != rawElement.getAttributeCount()) {
return false;
}
Enumeration<XMLAttribute> en = this.attributes.elements();
while (en.hasMoreElements()) {
XMLAttribute attr = (XMLAttribute) en.nextElement();
if (! rawElement.hasAttribute(attr.getName(), attr.getNamespace())) {
return false;
}
String value = rawElement.getAttribute(attr.getName(),
attr.getNamespace(),
null);
if (! attr.getValue().equals(value)) {
return false;
}
String type = rawElement.getAttributeType(attr.getName(),
attr.getNamespace());
if (! attr.getType().equals(type)) {
return false;
}
}
if (this.children.size() != rawElement.getChildCount()) {
return false;
}
for (int i = 0; i < this.children.size(); i++) {
XMLElement child1 = this.getChildAtIndex(i);
XMLElement child2 = rawElement.getChildAtIndex(i);
if (! child1.equalsXMLElement(child2)) {
return false;
}
}
return true;
}
public String toString() {
return toString(true);
}
public String toString(boolean pretty) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(baos);
XMLWriter writer = new XMLWriter(osw);
try {
if (pretty) {
writer.write(this, true, 2, true);
} else {
writer.write(this, false, 0, true);
}
} catch (IOException e) {
e.printStackTrace();
}
return baos.toString();
}
}