001: package net.sf.saxon.tinytree;
002:
003: import net.sf.saxon.om.AxisIteratorImpl;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.om.NodeInfo;
007: import net.sf.saxon.pattern.NameTest;
008: import net.sf.saxon.pattern.NodeTest;
009: import net.sf.saxon.type.Type;
010: import net.sf.saxon.value.UntypedAtomicValue;
011: import net.sf.saxon.style.StandardNames;
012:
013: /**
014: * AttributeEnumeration is an iterator over all the attribute nodes of an Element.
015: */
016:
017: final class AttributeEnumeration extends AxisIteratorImpl {
018:
019: private TinyTree tree;
020: private int element;
021: private NodeTest nodeTest;
022: private int index;
023:
024: /**
025: * Constructor. Note: this constructor will only be called if the relevant node
026: * is an element and if it has one or more attributes. Otherwise an EmptyEnumeration
027: * will be constructed instead.
028: * @param tree: the containing TinyTree
029: * @param element: the node number of the element whose attributes are required
030: * @param nodeTest: condition to be applied to the names of the attributes selected
031: */
032:
033: AttributeEnumeration(TinyTree tree, int element, NodeTest nodeTest) {
034:
035: this .nodeTest = nodeTest;
036: this .tree = tree;
037: this .element = element;
038: index = tree.alpha[element];
039: }
040:
041: /**
042: * Get the next node in the iteration.
043: */
044:
045: public Item next() {
046: while (true) {
047: if (index >= tree.numberOfAttributes
048: || tree.attParent[index] != element) {
049: index = Integer.MAX_VALUE;
050: current = null;
051: position = -1;
052: return null;
053: }
054: int typeCode = tree.getAttributeAnnotation(index);
055: if ((typeCode & NodeInfo.IS_DTD_TYPE) != 0) {
056: typeCode = StandardNames.XDT_UNTYPED_ATOMIC;
057: }
058: if (nodeTest.matches(Type.ATTRIBUTE, tree.attCode[index],
059: typeCode)) {
060: position++;
061: int nodeNr = index++;
062: if (nodeTest instanceof NameTest) {
063: // there can only be one match, so abandon the search after this node
064: index = Integer.MAX_VALUE;
065: }
066: if (isAtomizing()
067: && typeCode == StandardNames.XDT_UNTYPED_ATOMIC) {
068: // optimization: avoid creating the Node object if not needed
069: current = new UntypedAtomicValue(
070: tree.attValue[nodeNr]);
071: return current;
072: } else {
073: current = tree.getAttributeNode(nodeNr);
074: return current;
075: }
076: }
077: index++;
078: }
079: }
080:
081: /**
082: * Get another iteration over the same nodes
083: */
084:
085: public SequenceIterator getAnother() {
086: return new AttributeEnumeration(tree, element, nodeTest);
087: }
088:
089: }
090:
091: //
092: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
093: // you may not use this file except in compliance with the License. You may obtain a copy of the
094: // License at http://www.mozilla.org/MPL/
095: //
096: // Software distributed under the License is distributed on an "AS IS" basis,
097: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
098: // See the License for the specific language governing rights and limitations under the License.
099: //
100: // The Original Code is: all this file.
101: //
102: // The Initial Developer of the Original Code is Michael H. Kay.
103: //
104: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
105: //
106: // Contributor(s): none.
107: //
|