You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by cu...@locus.apache.org on 2000/07/19 21:20:58 UTC

cvs commit: xml-xalan/src/org/apache/xalan/xpath SimpleNodeLocator.java

curcuru     00/07/19 12:20:57

  Modified:    src/org/apache/xalan/xpath SimpleNodeLocator.java
  Log:
  namespace::* axis fix: added AttrProxy inner class and updated findNamespace()
  PR:DMAN4KPPSQ
  Submitted by:<ke...@haun.org>
  
  Revision  Changes    Path
  1.24      +98 -13    xml-xalan/src/org/apache/xalan/xpath/SimpleNodeLocator.java
  
  Index: SimpleNodeLocator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/SimpleNodeLocator.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- SimpleNodeLocator.java	2000/05/17 22:39:40	1.23
  +++ SimpleNodeLocator.java	2000/07/19 19:20:56	1.24
  @@ -60,7 +60,8 @@
   import java.io.*;
   import org.w3c.dom.*;
   import org.apache.xalan.xpath.res.XPATHErrorResources;
  -import  org.apache.xalan.xpath.xml.ProblemListenerDefault;
  +import org.apache.xalan.xpath.xml.ProblemListenerDefault;
  +import org.apache.xalan.xpath.xml.PrefixResolverDefault;
   
   /**
    * <meta name="usage" content="advanced"/>
  @@ -675,7 +676,93 @@
       }
       return subQueryResults;
     }
  -  
  +
  +  /**
  +   * Tricky implementation to realize returning correct namespace nodes.
  +   * // PATCH {blocks} PR:DMAN4KPPSQ Submitted by:<ke...@haun.org> namespace::* axis fix
  +   */
  +  private static class AttrProxy implements Attr {
  +    Attr real;
  +    Element owner;
  +    AttrProxy(Node owner, Document factory, String name, String value) {
  +      this.real = factory.createAttribute(name);
  +      this.real.setValue(value);
  +      this.owner = (Element)owner;
  +    }
  +    public Element getOwnerElement() {
  +      return this.owner;
  +    }
  +
  +    public String getName() {  return this.real.getName(); }
  +    public boolean getSpecified() {  return false; }
  +    public String getValue() {  return this.real.getValue(); }
  +    public void setValue(String value) {  this.real.setValue(value); }
  +
  +    public Node appendChild(Node newChild) {  return this.real.appendChild(newChild);  }
  +    public Node cloneNode(boolean deep) {  return this.real.cloneNode(deep);  }
  +    public NamedNodeMap getAttributes() {  return this.real.getAttributes();  }
  +    public NodeList getChildNodes() {  return this.real.getChildNodes();  }
  +    public Node getFirstChild() {  return this.real.getFirstChild();  }
  +    public Node getLastChild() {  return this.real.getLastChild();  }
  +    public String getLocalName() {  return this.real.getLocalName();  }
  +    public String getNamespaceURI() {  return this.real.getNamespaceURI();  }
  +    public Node getNextSibling() {  return this.real.getNextSibling();  }
  +    public String getNodeName() {  return this.real.getNodeName();  }
  +    public short getNodeType() {  return this.real.getNodeType();  }
  +    public String getNodeValue() {  return this.real.getNodeValue();  }
  +    public Document getOwnerDocument() {  return this.real.getOwnerDocument();  }
  +    public Node getParentNode() {  return this.real.getParentNode();  }
  +    public String getPrefix() {  return this.real.getPrefix();  }
  +    public Node getPreviousSibling() {  return this.real.getPreviousSibling();  }
  +    public boolean hasChildNodes() {  return this.real.hasChildNodes();  }
  +    public Node insertBefore(Node newChild, Node refChild) {
  +      return this.real.insertBefore(newChild, refChild);  }
  +    public void normalize() {  this.real.normalize();  }
  +    public Node removeChild(Node oldChild) {  return this.real.removeChild(oldChild);  }
  +    public Node replaceChild(Node newChild, Node oldChild) {
  +      return this.real.replaceChild(newChild, oldChild);  }
  +    public void setNodeValue(String nodeValue) {  this.real.setNodeValue(nodeValue);  }
  +    public void setPrefix(String prefix) {  this.real.setPrefix(prefix);  }
  +    public boolean supports(String feature, String version) {
  +      return this.real.supports(feature, version);  }
  +  }
  +
  +  private static final String S_XMLNAMESPACEURI = PrefixResolverDefault.S_XMLNAMESPACEURI;
  +  /**
  +   * Collects all namespace nodes that are effective in the <var>startNode<var>.
  +   * // PATCH {blocks} PR:DMAN4KPPSQ Submitted by:<ke...@haun.org> namespace::* axis fix
  +   * @param startNode A target element.
  +   * @return A hashtable; A key in the result is an attribute names such as "xmlns", "xmlns:foo".
  +   *         An element in the result is an <code>Attr</code> instance.
  +   */
  +  public static Hashtable collectNamespaceNodesInAncestors(Node startNode) {
  +    Node node = startNode;
  +    Hashtable nsnodes = new Hashtable();
  +    Document factory = startNode.getOwnerDocument(); // Null-check is not needed.
  +    nsnodes.put("xmlns:xml", new AttrProxy(startNode, factory, "xmlns:xml", S_XMLNAMESPACEURI));
  +    do {
  +      NamedNodeMap attributeList = node.getAttributes();
  +      if (attributeList != null) {
  +        int nAttrs = attributeList.getLength();
  +        for (int j = 0; j < nAttrs; j++) {
  +          Attr attr = (Attr)attributeList.item(j);
  +          String attrName = attr.getNodeName();
  +          if (attrName.equals("xmlns") || attrName.startsWith("xmlns:")) {
  +            if (!nsnodes.containsKey(attrName)) {
  +              if (node == startNode) {
  +                nsnodes.put(attrName, attr);
  +              } else {
  +                Attr newAttr = new AttrProxy(startNode, factory, attrName, attr.getNodeValue());
  +                nsnodes.put(attrName, newAttr);
  +              }
  +            }
  +          }
  +        }
  +      }
  +    } while ((node = node.getParentNode()) != null);
  +    return nsnodes;
  +  }
  +
     /**
      * Add the namespace node of the context.
      * @param xpath The xpath that is executing.
  @@ -696,18 +783,16 @@
       opPos = xpath.getFirstChildPosOfStep(opPos);
       if( (null != context) && (context.getNodeType()==Node.ELEMENT_NODE) )
       {
  -      NamedNodeMap attributeList = context.getAttributes();
  -      if( attributeList != null ) 
  -      {
  -        int nAttrs = attributeList.getLength();
  -        for( int j=0; j < nAttrs; j++ )
  +      // PATCH {blocks} PR:DMAN4KPPSQ Submitted by:<ke...@haun.org> namespace::* axis fix
  +      Hashtable nsnodes = collectNamespaceNodesInAncestors(context);
  +      Enumeration enum = nsnodes.keys();
  +      while (enum.hasMoreElements()) {
  +        String attrName = (String)enum.nextElement();
  +        Attr attr = (Attr)nsnodes.get(attrName);
  +        if(XPath.MATCH_SCORE_NONE != nodeTest(xpath, execContext, attr, opPos, argLen, stepType))
           {
  -          Attr attr = (Attr)attributeList.item(j);
  -          if(XPath.MATCH_SCORE_NONE != nodeTest(xpath, execContext, attr, opPos, argLen, stepType))
  -          {
  -            subQueryResults = addNode(subQueryResults, attr);
  -            // If we have an attribute name here, we can quit.
  -          }
  +          subQueryResults = addNode(subQueryResults, attr);
  +          // If we have an attribute name here, we can quit.
           }
         }
       }