All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.tree.ElementWithAttributes Maven / Gradle / Ivy

package net.sf.saxon.tree;
import net.sf.saxon.event.LocationCopier;
import net.sf.saxon.event.Receiver;
import net.sf.saxon.om.*;
import net.sf.saxon.sort.IntArraySet;
import net.sf.saxon.sort.IntIterator;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.Type;

import java.util.Iterator;

/**
  * A node in the XML parse tree representing an XML element.

* This class is an implementation of NodeInfo * @author Michael H. Kay * @version 8 August 2000: separated from ElementImpl */ // The name of the element and its attributes are now namespace-resolved by the // parser. However, this class retains the ability to do namespace resolution for other // names, for example variable and template names in a stylesheet. public class ElementWithAttributes extends ElementImpl implements NamespaceResolver { protected AttributeCollection attributeList; // this excludes namespace attributes protected int[] namespaceList = null; // list of namespace codes // note that this namespace list includes only the namespaces actually defined on // this element, not those inherited from outer elements. /** * Initialise a new ElementWithAttributes with an element name and attribute list * @param nameCode The element name, with namespaces resolved * @param atts The attribute list, after namespace processing * @param parent The parent node */ public void initialise(int nameCode, AttributeCollectionImpl atts, NodeInfo parent, String baseURI, int lineNumber, int sequenceNumber) { this.nameCode = nameCode; attributeList = atts; this.parent = (ParentNodeImpl)parent; sequence = sequenceNumber; root = (DocumentImpl)parent.getDocumentRoot(); root.setLineNumber(sequenceNumber, lineNumber); root.setSystemId(sequenceNumber, baseURI); } /** * Set the namespace declarations for the element * @param namespaces the list of namespace codes * @param namespacesUsed the number of entries in the list that are used */ public void setNamespaceDeclarations(int[] namespaces, int namespacesUsed) { namespaceList = new int[namespacesUsed]; System.arraycopy(namespaces, 0, namespaceList, 0, namespacesUsed); } /** * Get the namespace URI corresponding to a given prefix. Return null * if the prefix is not in scope. * * @param prefix the namespace prefix. May be the zero-length string, indicating * that there is no prefix. This indicates either the default namespace or the * null namespace, depending on the value of useDefault. * @param useDefault true if the default namespace is to be used when the * prefix is "". If false, the method returns "" when the prefix is "". * @return the uri for the namespace, or null if the prefix is not in scope. * The "null namespace" is represented by the pseudo-URI "". */ public String getURIForPrefix(String prefix, boolean useDefault) { if (prefix.equals("xml")) { return NamespaceConstant.XML; } if (prefix.length() == 0 && !useDefault) { return ""; } NamePool pool = getNamePool(); int prefixCode = pool.getCodeForPrefix(prefix); if (prefixCode==-1) { return null; } try { short uriCode = getURICodeForPrefixCode(prefixCode); return pool.getURIFromURICode(uriCode); } catch (NamespaceException e) { return null; } } /** * Get an iterator over all the prefixes declared in this namespace context. This will include * the default namespace (prefix="") and the XML namespace where appropriate */ public Iterator iteratePrefixes() { return new Iterator() { private NamePool pool = null; private IntIterator iter = NamespaceCodeIterator.iterateNamespaces(ElementWithAttributes.this); public boolean hasNext() { return (pool == null || iter.hasNext()); } public Object next() { if (pool == null) { pool = getNamePool(); return "xml"; } else { return pool.getPrefixFromNamespaceCode(iter.next()); } } public void remove() { throw new UnsupportedOperationException("remove"); } }; } /** * Search the NamespaceList for a given prefix, returning the corresponding URI. * @param prefix The prefix to be matched. To find the default namespace, supply "" * @return The URI code corresponding to this namespace. If it is an unnamed default namespace, * return Namespace.NULL_CODE. * @throws NamespaceException if the prefix has not been declared on this NamespaceList. */ public short getURICodeForPrefix(String prefix) throws NamespaceException { if (prefix.equals("xml")) return NamespaceConstant.XML_CODE; NamePool pool = getNamePool(); int prefixCode = pool.getCodeForPrefix(prefix); if (prefixCode==-1) { throw new NamespaceException(prefix); } return getURICodeForPrefixCode(prefixCode); } private short getURICodeForPrefixCode(int prefixCode) throws NamespaceException { if (namespaceList!=null) { for (int i=0; i>16) == prefixCode) { return (short)(namespaceList[i] & 0xffff); } } } NodeInfo next = parent; while (true) { if (next.getNodeKind()==Type.DOCUMENT) { // prefixCode==0 represents the empty namespace prefix "" if (prefixCode==0) return NamespaceConstant.NULL_CODE; throw new NamespaceException(getNamePool().getPrefixFromNamespaceCode(prefixCode<<16)); } else if (next instanceof ElementWithAttributes) { return ((ElementWithAttributes)next).getURICodeForPrefixCode(prefixCode); } else { next = next.getParent(); } } } /** * Search the NamespaceList for a given URI, returning the corresponding prefix. * @param uri The URI to be matched. * @return The prefix corresponding to this URI. If not found, return null. If there is * more than one prefix matching the URI, the first one found is returned. If the URI matches * the default namespace, return an empty string. */ public String getPrefixForURI(String uri) { if (uri.equals(NamespaceConstant.XML)) return "xml"; NamePool pool = getNamePool(); int uriCode = pool.getCodeForURI(uri); if (uriCode<0) return null; return getPrefixForURICode(uriCode); } private String getPrefixForURICode(int code) { if (namespaceList!=null) { for (int i=0; i *

For a node other than an element, the method returns null.

*/ public int[] getDeclaredNamespaces(int[] buffer) { return (namespaceList == null ? IntArraySet.EMPTY_INT_ARRAY : namespaceList); } /** * Get the list of in-scope namespaces for this element as an array of * namespace codes. (Used by LiteralResultElement) * @return the list of namespaces */ public int[] getInScopeNamespaceCodes() { return NamespaceIterator.getInScopeNamespaceCodes(this); } /** * Get the attribute list for this element. * @return The attribute list. This will not include any * namespace attributes. The attribute names will be in expanded form, with prefixes * replaced by URIs */ public AttributeCollection getAttributeList() { return attributeList; } /** * Get the value of a given attribute of this node * @param fingerprint The fingerprint of the attribute name * @return the attribute value if it exists or null if not */ public String getAttributeValue(int fingerprint) { return attributeList.getValueByFingerprint(fingerprint); } /** * Copy this node to a given outputter (supporting xsl:copy-of) * @param out The outputter * @param whichNamespaces indicates which namespaces should be output: all, none, or local * namespaces only (those not declared on the parent element) */ public void copy(Receiver out, int whichNamespaces, boolean copyAnnotations, int locationId) throws XPathException { int typeCode = (copyAnnotations ? getTypeAnnotation() : -1); if (locationId == 0 && out instanceof LocationCopier) { out.setSystemId(getBaseURI()); ((LocationCopier)out).setLineNumber(getLineNumber()); } out.startElement(getNameCode(), typeCode, locationId, 0); // output the namespaces switch (whichNamespaces) { case NodeInfo.NO_NAMESPACES: break; case NodeInfo.LOCAL_NAMESPACES: int[] localNamespaces = getDeclaredNamespaces(null); for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy