001: package net.sf.saxon.tree;
002:
003: import net.sf.saxon.event.Receiver;
004: import net.sf.saxon.om.AttributeCollection;
005: import net.sf.saxon.om.NodeInfo;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.Type;
008:
009: /**
010: * A node in the XML parse tree representing an attribute. Note that this is
011: * generated only "on demand", when the attribute is selected by a select pattern.<P>
012: * @author Michael H. Kay
013: */
014:
015: final class AttributeImpl extends NodeImpl {
016:
017: private int nameCode;
018: private int typeCode;
019: private String value;
020:
021: /**
022: * Construct an Attribute node for the n'th attribute of a given element
023: * @param element The element containing the relevant attribute
024: * @param index The index position of the attribute starting at zero
025: */
026:
027: public AttributeImpl(ElementImpl element, int index) {
028: parent = element;
029: this .index = index;
030: AttributeCollection atts = element.getAttributeList();
031: this .nameCode = atts.getNameCode(index);
032: this .value = atts.getValue(index);
033: this .typeCode = atts.getTypeAnnotation(index);
034: }
035:
036: /**
037: * Get the name code, which enables the name to be located in the name pool
038: */
039:
040: public int getNameCode() {
041: return nameCode;
042: }
043:
044: /**
045: * Get the type annotation of this node, if any
046: */
047:
048: public int getTypeAnnotation() {
049: return typeCode;
050: }
051:
052: /**
053: * Determine whether this is the same node as another node
054: * @return true if this Node object and the supplied Node object represent the
055: * same node in the tree.
056: */
057:
058: public boolean isSameNodeInfo(NodeInfo other) {
059: if (!(other instanceof AttributeImpl))
060: return false;
061: if (this == other)
062: return true;
063: AttributeImpl otherAtt = (AttributeImpl) other;
064: return (parent.isSameNodeInfo(otherAtt.parent) && ((nameCode & 0xfffff) == (otherAtt.nameCode & 0xfffff)));
065: }
066:
067: /**
068: * Get the node sequence number (in document order). Sequence numbers are monotonic but not
069: * consecutive. In the current implementation, parent nodes (elements and roots) have a zero
070: * least-significant word, while namespaces, attributes, text nodes, comments, and PIs have
071: * the top word the same as their owner and the bottom half reflecting their relative position.
072: */
073:
074: protected long getSequenceNumber() {
075: return parent.getSequenceNumber() + 0x8000 + index;
076: // note the 0x8000 is to leave room for namespace nodes
077: }
078:
079: /**
080: * Return the type of node.
081: * @return Node.ATTRIBUTE
082: */
083:
084: public final int getNodeKind() {
085: return Type.ATTRIBUTE;
086: }
087:
088: /**
089: * Return the character value of the node.
090: * @return the attribute value
091: */
092:
093: public String getStringValue() {
094: return value;
095: }
096:
097: /**
098: * Get next sibling - not defined for attributes
099: */
100:
101: public NodeInfo getNextSibling() {
102: return null;
103: }
104:
105: /**
106: * Get previous sibling - not defined for attributes
107: */
108:
109: public NodeInfo getPreviousSibling() {
110: return null;
111: }
112:
113: /**
114: * Get the previous node in document order (skipping attributes)
115: */
116:
117: public NodeImpl getPreviousInDocument() {
118: return (NodeImpl) getParent();
119: }
120:
121: /**
122: * Get the next node in document order (skipping attributes)
123: */
124:
125: public NodeImpl getNextInDocument(NodeImpl anchor) {
126: if (anchor == this )
127: return null;
128: return ((NodeImpl) getParent()).getNextInDocument(anchor);
129: }
130:
131: /**
132: * Get sequential key. Returns key of owning element with the attribute index as a suffix
133: */
134:
135: public String generateId() {
136: return parent.generateId() + 'a' + index;
137: }
138:
139: /**
140: * Copy this node to a given outputter
141: */
142:
143: public void copy(Receiver out, int whichNamespaces,
144: boolean copyAnnotations, int locationId)
145: throws XPathException {
146: int nameCode = getNameCode();
147: int typeCode = (copyAnnotations ? getTypeAnnotation() : -1);
148: out.attribute(nameCode, typeCode, getStringValue(), locationId,
149: 0);
150: }
151:
152: }
153:
154: //
155: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
156: // you may not use this file except in compliance with the License. You may obtain a copy of the
157: // License at http://www.mozilla.org/MPL/
158: //
159: // Software distributed under the License is distributed on an "AS IS" basis,
160: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
161: // See the License for the specific language governing rights and limitations under the License.
162: //
163: // The Original Code is: all this file.
164: //
165: // The Initial Developer of the Original Code is Michael H. Kay.
166: //
167: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
168: //
169: // Contributor(s): none.
170: //
|