001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: PrefixResolverDefault.java 468655 2006-10-28 07:12:06Z minchau $
020 */
021 package org.apache.xml.utils;
022
023 import org.w3c.dom.NamedNodeMap;
024 import org.w3c.dom.Node;
025
026 /**
027 * This class implements a generic PrefixResolver that
028 * can be used to perform prefix-to-namespace lookup
029 * for the XPath object.
030 * @xsl.usage general
031 */
032 public class PrefixResolverDefault implements PrefixResolver
033 {
034
035 /**
036 * The context to resolve the prefix from, if the context
037 * is not given.
038 */
039 Node m_context;
040
041 /**
042 * Construct a PrefixResolverDefault object.
043 * @param xpathExpressionContext The context from
044 * which XPath expression prefixes will be resolved.
045 * Warning: This will not work correctly if xpathExpressionContext
046 * is an attribute node.
047 */
048 public PrefixResolverDefault(Node xpathExpressionContext)
049 {
050 m_context = xpathExpressionContext;
051 }
052
053 /**
054 * Given a namespace, get the corrisponding prefix. This assumes that
055 * the PrevixResolver hold's it's own namespace context, or is a namespace
056 * context itself.
057 * @param prefix Prefix to resolve.
058 * @return Namespace that prefix resolves to, or null if prefix
059 * is not bound.
060 */
061 public String getNamespaceForPrefix(String prefix)
062 {
063 return getNamespaceForPrefix(prefix, m_context);
064 }
065
066 /**
067 * Given a namespace, get the corrisponding prefix.
068 * Warning: This will not work correctly if namespaceContext
069 * is an attribute node.
070 * @param prefix Prefix to resolve.
071 * @param namespaceContext Node from which to start searching for a
072 * xmlns attribute that binds a prefix to a namespace.
073 * @return Namespace that prefix resolves to, or null if prefix
074 * is not bound.
075 */
076 public String getNamespaceForPrefix(String prefix,
077 org.w3c.dom.Node namespaceContext)
078 {
079
080 Node parent = namespaceContext;
081 String namespace = null;
082
083 if (prefix.equals("xml"))
084 {
085 namespace = Constants.S_XMLNAMESPACEURI;
086 }
087 else
088 {
089 int type;
090
091 while ((null != parent) && (null == namespace)
092 && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
093 || (type == Node.ENTITY_REFERENCE_NODE)))
094 {
095 if (type == Node.ELEMENT_NODE)
096 {
097 if (parent.getNodeName().indexOf(prefix+":") == 0)
098 return parent.getNamespaceURI();
099 NamedNodeMap nnm = parent.getAttributes();
100
101 for (int i = 0; i < nnm.getLength(); i++)
102 {
103 Node attr = nnm.item(i);
104 String aname = attr.getNodeName();
105 boolean isPrefix = aname.startsWith("xmlns:");
106
107 if (isPrefix || aname.equals("xmlns"))
108 {
109 int index = aname.indexOf(':');
110 String p = isPrefix ? aname.substring(index + 1) : "";
111
112 if (p.equals(prefix))
113 {
114 namespace = attr.getNodeValue();
115
116 break;
117 }
118 }
119 }
120 }
121
122 parent = parent.getParentNode();
123 }
124 }
125
126 return namespace;
127 }
128
129 /**
130 * Return the base identifier.
131 *
132 * @return null
133 */
134 public String getBaseIdentifier()
135 {
136 return null;
137 }
138 /**
139 * @see PrefixResolver#handlesNullPrefixes()
140 */
141 public boolean handlesNullPrefixes() {
142 return false;
143 }
144
145 }