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 // $Id: JAXPPrefixResolver.java 468655 2006-10-28 07:12:06Z minchau $
019
020 package org.apache.xpath.jaxp;
021
022 import org.w3c.dom.Node;
023 import org.w3c.dom.NamedNodeMap;
024 import org.apache.xml.utils.PrefixResolver;
025
026 import javax.xml.namespace.NamespaceContext;
027
028 /**
029 * <meta name="usage" content="general"/>
030 * This class implements a Default PrefixResolver which
031 * can be used to perform prefix-to-namespace lookup
032 * for the XPath object.
033 * This class delegates the resolution to the passed NamespaceContext
034 */
035 public class JAXPPrefixResolver implements PrefixResolver
036 {
037
038 private NamespaceContext namespaceContext;
039
040
041 public JAXPPrefixResolver ( NamespaceContext nsContext ) {
042 this.namespaceContext = nsContext;
043 }
044
045
046 public String getNamespaceForPrefix( String prefix ) {
047 return namespaceContext.getNamespaceURI( prefix );
048 }
049
050 /**
051 * Return the base identifier.
052 *
053 * @return null
054 */
055 public String getBaseIdentifier() {
056 return null;
057 }
058
059 /**
060 * @see PrefixResolver#handlesNullPrefixes()
061 */
062 public boolean handlesNullPrefixes() {
063 return false;
064 }
065
066
067 /**
068 * The URI for the XML namespace.
069 * (Duplicate of that found in org.apache.xpath.XPathContext).
070 */
071
072 public static final String S_XMLNAMESPACEURI =
073 "http://www.w3.org/XML/1998/namespace";
074
075
076 /**
077 * Given a prefix and a Context Node, get the corresponding namespace.
078 * Warning: This will not work correctly if namespaceContext
079 * is an attribute node.
080 * @param prefix Prefix to resolve.
081 * @param namespaceContext Node from which to start searching for a
082 * xmlns attribute that binds a prefix to a namespace.
083 * @return Namespace that prefix resolves to, or null if prefix
084 * is not bound.
085 */
086 public String getNamespaceForPrefix(String prefix,
087 org.w3c.dom.Node namespaceContext) {
088 Node parent = namespaceContext;
089 String namespace = null;
090
091 if (prefix.equals("xml")) {
092 namespace = S_XMLNAMESPACEURI;
093 } else {
094 int type;
095
096 while ((null != parent) && (null == namespace)
097 && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
098 || (type == Node.ENTITY_REFERENCE_NODE))) {
099
100 if (type == Node.ELEMENT_NODE) {
101 NamedNodeMap nnm = parent.getAttributes();
102
103 for (int i = 0; i < nnm.getLength(); i++) {
104 Node attr = nnm.item(i);
105 String aname = attr.getNodeName();
106 boolean isPrefix = aname.startsWith("xmlns:");
107
108 if (isPrefix || aname.equals("xmlns")) {
109 int index = aname.indexOf(':');
110 String p =isPrefix ?aname.substring(index + 1) :"";
111
112 if (p.equals(prefix)) {
113 namespace = attr.getNodeValue();
114 break;
115 }
116 }
117 }
118 }
119
120 parent = parent.getParentNode();
121 }
122 }
123 return namespace;
124 }
125
126 }
127