You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by mk...@ca.ibm.com on 2002/07/25 21:21:43 UTC

[PATCH] patch for bug #5389

Hi,

Here you can find the patch for bug 5389
(http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5389).

The patch is a little bit long because I have to consider all variations of
the original problem.  I'd be appreciated
if anyone has time  to review it.

Morris Kwan
XSLT Development
IBM Toronto Lab
Tel: (905)413-3729
Email: mkwan@ca.ibm.com


Index: ElemAttribute.java
===================================================================
RCS file: /home/cvspublic/xml-xalan/java/src/org/apache/xalan/templates/ElemAttribute.java,v
retrieving revision 1.18
diff -u -r1.18 ElemAttribute.java
--- ElemAttribute.java  10 Jul 2002 16:06:31 -0000    1.18
+++ ElemAttribute.java  24 Jul 2002 21:19:24 -0000
@@ -70,6 +70,8 @@
 import org.apache.xpath.XPathContext;

 import org.xml.sax.SAXException;
+import java.util.Enumeration;
+import java.util.Vector;

 /**
  * <meta name="usage" content="advanced"/>
@@ -180,6 +182,14 @@
           prefix = "";
       }
     }
+    else if (prefix != null && needUniqueNSPrefix(prefix, nodeNamespace))
+    {
+      if(nodeNamespace.length() > 0)
+      {
+        prefix = rhandler.getNewUniqueNSPrefix();
+      }
+    }
+
     return prefix;
   }

@@ -237,7 +247,132 @@
     }
   }

+  /**
+   * Do we need to create a new unique prefix for the given prefix
+   * and namespace?
+   * A unique namespace prefix is needed when the same prefix has been used in the
+   * preceding context but associated with a different namespace.
+   *
+   * @param prefix The prefix
+   * @param namespace The namespace
+   *
+   * @return true if a unique prefix is needed.
+   */
+  private boolean needUniqueNSPrefix(String prefix, String namespace)
+  {
+
+    if (prefix == null || namespace == null)
+      return false;
+
+    ElemTemplateElement parent = getParentElem();
+
+    // Element specific tests, i.e. tests that depend on the type of the parent element.
+    //
+    // If the parent is a literal result element, check the element
+    // name and attribute list.
+    if (parent instanceof ElemLiteralResult)
+    {
+      ElemLiteralResult literalResult = (ElemLiteralResult)parent;
+      String rawName = literalResult.getRawName();
+
+      // Check whether the prefix is used in the literal result element's raw name.
+      if (prefix.equals(getPrefix(rawName)))
+      {
+        return true;
+      }
+      else
+      {
+        // Check whether the prefix is used in any of the parent's attributes.
+        Enumeration enum = literalResult.enumerateLiteralResultAttributes();
+        if (enum != null)
+        {
+          while (enum.hasMoreElements())
+          {
+            AVT avt = (AVT)enum.nextElement();
+            String avtName = avt.getRawName();
+            if (prefix.equals(getPrefix(avtName)))
+              return true;
+          }
+        }
+      }
+    }
+    // If the parent is a xsl:element, check the element's name and namespace.
+    else if (parent instanceof ElemElement)
+    {
+      ElemElement element = (ElemElement)parent;
+      AVT name_avt = element.getName();
+      AVT namespace_avt = element.getNamespace();
+      if (name_avt != null)
+      {
+        String qname = name_avt.getSimpleString();
+        if (prefix.equals(getPrefix(qname)))
+        {
+          if (namespace_avt == null || !namespace.equals(namespace_avt.getSimpleString()))
+            return true;
+        }
+      }
+    }

+    // General tests
+    if (parent != null)
+    {
+      // Check whether the prefix appears in the declared prefixes of the parent element.
+      Vector prefixes = parent.getDeclaredPrefixes();
+      if (prefixes != null)
+      {
+        Enumeration enum = prefixes.elements();
+        while (enum.hasMoreElements())
+        {
+          XMLNSDecl nsDecl = (XMLNSDecl)enum.nextElement();
+          if (prefix.equals(nsDecl.getPrefix()))
+            return true;
+        }
+      }
+
+      // Check whether the prefix is used in any of the child attribute elements
+      // of the parent element.
+      ElemTemplateElement child = parent.getFirstChildElem();
+      while (child != null && child != this)
+      {
+        if (child instanceof ElemAttribute)
+        {
+          ElemAttribute attribute = (ElemAttribute)child;
+          AVT name_avt = attribute.getName();
+          AVT namespace_avt = attribute.getNamespace();
+          if (name_avt != null)
+          {
+            String qname = name_avt.getSimpleString();
+            if (prefix.equals(getPrefix(qname)))
+            {
+              if (namespace_avt == null || !namespace.equals(namespace_avt.getSimpleString()))
+                return true;
+            }
+          }
+        }
+
+        child = child.getNextSiblingElem();
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Return the prefix of a qualified name.
+   *
+   * @param qName The qualified name
+   *
+   * @return The prefix of the qualified name
+   */
+  private String getPrefix(String qName)
+  {
+    if (qName == null)
+      return null;
+
+    int index = qName.indexOf(':');
+    return (index > 0 ? qName.substring(0, index) : null);
+  }
+
   /**
    * Add a child to the child list.
    * <!ELEMENT xsl:attribute %char-template;>