/** * Creates a (possibly empty) <CODE>NodeList</CODE> containing all the element nodes of a given * type (or a derived sub-type). * * @param ns The required namespace URI. * @param type The required type name. * @return A <CODE>NodeList</CODE> of corresponding nodes. * @since TFP 1.1 */ public NodeList getElementsByType(final String ns, final String type) { Vector<TypeInfo> matches = compatibleTypes.get(type); if (matches == null) { compatibleTypes.put(type, matches = new Vector<TypeInfo>()); // System.err.println ("%% Looking for " + ns + ":" + type); Enumeration<String> cursor = typesByName.keys(); while (cursor.hasMoreElements()) { String key = (String) cursor.nextElement(); Vector<TypeInfo> types = typesByName.get(key); for (int index = 0; index < types.size(); ++index) { TypeInfo info = types.elementAt(index); if (type.equals(info.getTypeName()) || info.isDerivedFrom( ns, type, TypeInfo.DERIVATION_EXTENSION | TypeInfo.DERIVATION_RESTRICTION)) { matches.add(info); // System.err.println ("%% Found: " + info.getTypeName ()); } } } } MutableNodeList result = new MutableNodeList(); for (int index = 0; index < matches.size(); ++index) { TypeInfo info = matches.elementAt(index); NodeList nodes = elementsByType.get(info.getTypeName()); // System.err.println ("-- Matching elements of type: " + info.getTypeName ()); for (int count = 0; count < nodes.getLength(); ++count) { Element element = (Element) nodes.item(count); TypeInfo typeInfo = element.getSchemaTypeInfo(); if (typeInfo.getTypeName().equals(info.getTypeName()) && typeInfo.getTypeNamespace().equals(info.getTypeNamespace())) { result.add(element); // System.err.println ("-- Matched: " + element.getLocalName ()); } } } return (result); }
/** * Recursively walks a DOM tree creating an index of the elements by their local name. * * @param node The next node to be indexed. * @since TFP 1.0 */ private void indexNodes(Node node) { switch (node.getNodeType()) { case Node.DOCUMENT_NODE: indexNodes(((Document) node).getDocumentElement()); break; case Node.ELEMENT_NODE: { String name = ((Element) node).getLocalName(); MutableNodeList list = (MutableNodeList) elementsByName.get(name); if (list == null) elementsByName.put(name, list = new MutableNodeList()); list.add(node); TypeInfo typeInfo = ((Element) node).getSchemaTypeInfo(); if ((typeInfo != null) && ((name = typeInfo.getTypeName()) != null)) { Vector<TypeInfo> types = typesByName.get(name); int index; if (types == null) typesByName.put(name, types = new Vector<TypeInfo>()); for (index = 0; index < types.size(); ++index) { TypeInfo info = (TypeInfo) types.elementAt(index); if (typeInfo.getTypeNamespace().equals(info.getTypeNamespace())) break; } if (index == types.size()) types.add(typeInfo); list = (MutableNodeList) elementsByType.get(name); if (list == null) elementsByType.put(name, list = new MutableNodeList()); list.add(node); } Attr id = ((Element) node).getAttributeNode("id"); if (id != null) elementsById.put(id.getValue(), node); NamedNodeMap map = ((Element) node).getAttributes(); for (int index = 0; index < map.getLength(); ++index) { Attr attr = (Attr) map.item(index); list = (MutableNodeList) attributesByName.get(attr.getName()); if (list == null) attributesByName.put(attr.getName(), list = new MutableNodeList()); list.add(attr); } for (Node child = node.getFirstChild(); child != null; ) { if (child.getNodeType() == Node.ELEMENT_NODE) indexNodes(child); child = child.getNextSibling(); } break; } } }