You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@apache.org on 2001/01/04 09:06:25 UTC

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

sboag       01/01/04 00:06:25

  Modified:    java/src/org/apache/xalan/stree Child.java ElementImpl.java
                        TextImpl.java
               java/src/org/apache/xalan/templates ElemTemplateElement.java
                        Stylesheet.java StylesheetRoot.java
               java/src/org/apache/xml/utils XMLCharacterRecognizer.java
               java/src/org/apache/xpath/axes ChildIterator.java
               java/src/org/apache/xpath/patterns NodeTest.java
  Added:       java/src/org/apache/xpath
                        WhitespaceStrippingElementMatcher.java
  Log:
  Implement xsl:strip-space functionality for generic DOMs, somewhat
  against my better judgement, at some (slight) expense to all processing,
  and at great risk to my sanity.
  
  Revision  Changes    Path
  1.15      +1 -1      xml-xalan/java/src/org/apache/xalan/stree/Child.java
  
  Index: Child.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/stree/Child.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Child.java	2000/12/31 09:41:43	1.14
  +++ Child.java	2001/01/04 08:06:22	1.15
  @@ -364,7 +364,7 @@
      * @return Returns <code>true</code> if the specified feature is supported
      *   on this node, <code>false</code> otherwise.
      */
  -  public boolean supports(String feature, String version)
  +  public boolean isSupported(String feature, String version)
     {
       return false;
     }
  
  
  
  1.23      +1 -1      xml-xalan/java/src/org/apache/xalan/stree/ElementImpl.java
  
  Index: ElementImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/stree/ElementImpl.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- ElementImpl.java	2001/01/02 03:36:43	1.22
  +++ ElementImpl.java	2001/01/04 08:06:22	1.23
  @@ -874,7 +874,7 @@
     {
       return getChildAttribute(index);
     }
  -
  +  
     /**
      *  Retrieves a node specified by local name and namespace URI. HTML-only
      * DOM implementations do not need to implement this method.
  
  
  
  1.11      +4 -3      xml-xalan/java/src/org/apache/xalan/stree/TextImpl.java
  
  Index: TextImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/stree/TextImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- TextImpl.java	2001/01/02 03:36:43	1.10
  +++ TextImpl.java	2001/01/04 08:06:22	1.11
  @@ -241,10 +241,11 @@
      *
      * @return true if feature is SaxEventDispatch.SUPPORTSINTERFACE 
      */
  -  public boolean supports(String feature, String version)
  +  public boolean isSupported(String feature, String version)
     {
   
  -    if (feature == SaxEventDispatch.SUPPORTSINTERFACE)
  +    if (feature == SaxEventDispatch.SUPPORTSINTERFACE ||
  +        feature == org.apache.xpath.patterns.NodeTest.SUPPORTS_PRE_STRIPPING)
         return true;
       else
         return false;
  @@ -252,7 +253,7 @@
       // else if(feature.equals(SaxEventDispatch.SUPPORTSINTERFACE))
       //  return true;
       // else
  -    //  return super.supports(feature, version);
  +    //  return super.isSupported(feature, version);
     }
     
     /**
  
  
  
  1.35      +34 -1     xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java
  
  Index: ElemTemplateElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemTemplateElement.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- ElemTemplateElement.java	2001/01/02 03:36:46	1.34
  +++ ElemTemplateElement.java	2001/01/04 08:06:23	1.35
  @@ -75,6 +75,7 @@
   import org.apache.xalan.transformer.ResultNameSpace;
   import org.apache.xalan.transformer.ResultTreeHandler;
   import org.apache.xpath.VariableStack;
  +import org.apache.xpath.WhitespaceStrippingElementMatcher;
   
   // TRaX imports
   import javax.xml.transform.Templates;
  @@ -105,7 +106,8 @@
    * @see Stylesheet
    */
   public class ElemTemplateElement extends UnImplNode
  -        implements PrefixResolver, Serializable, SourceLocator
  +        implements PrefixResolver, Serializable, SourceLocator, 
  +                   WhitespaceStrippingElementMatcher
   {
   
     /**
  @@ -1195,6 +1197,37 @@
         return 1;
       else
         return this.getUid() - ro.getUid();
  +  }
  +  
  +  /**
  +   * Get information about whether or not an element should strip whitespace.
  +   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  +   *
  +   * @param support The XPath runtime state.
  +   * @param targetElement Element to check
  +   *
  +   * @return true if the whitespace should be stripped.
  +   *
  +   * @throws TransformerException
  +   */
  +  public boolean shouldStripWhiteSpace(
  +          org.apache.xpath.XPathContext support, 
  +          org.w3c.dom.Element targetElement) throws TransformerException
  +  {
  +    StylesheetRoot sroot = this.getStylesheetRoot();
  +    return (null != sroot) ? sroot.shouldStripWhiteSpace(support, targetElement) :false;
  +  }
  +  
  +  /**
  +   * Get information about whether or not whitespace can be stripped.
  +   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  +   *
  +   * @return true if the whitespace can be stripped.
  +   */
  +  public boolean canStripWhiteSpace()
  +  {
  +    StylesheetRoot sroot = this.getStylesheetRoot();
  +    return (null != sroot) ? sroot.canStripWhiteSpace() : false;
     }
   
   }
  
  
  
  1.22      +1 -0      xml-xalan/java/src/org/apache/xalan/templates/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/Stylesheet.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- Stylesheet.java	2001/01/02 03:36:47	1.21
  +++ Stylesheet.java	2001/01/04 08:06:23	1.22
  @@ -1398,4 +1398,5 @@
       m_templates.setElementAt(v, i);
       v.setStylesheet(this);
     }
  +  
   }
  
  
  
  1.37      +46 -0     xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java
  
  Index: StylesheetRoot.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/StylesheetRoot.java,v
  retrieving revision 1.36
  retrieving revision 1.37
  diff -u -r1.36 -r1.37
  --- StylesheetRoot.java	2001/01/02 03:36:47	1.36
  +++ StylesheetRoot.java	2001/01/04 08:06:23	1.37
  @@ -828,6 +828,52 @@
       else
         return null;
     }
  +  
  +  /**
  +   * Get information about whether or not an element should strip whitespace.
  +   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  +   *
  +   * @param support The XPath runtime state.
  +   * @param targetElement Element to check
  +   *
  +   * @return true if the whitespace should be stripped.
  +   *
  +   * @throws TransformerException
  +   */
  +  public boolean shouldStripWhiteSpace(
  +          XPathContext support, Element targetElement) throws TransformerException
  +  {
  +    if (null != m_whiteSpaceInfoList)
  +    {
  +      while(null != targetElement)
  +      {
  +        WhiteSpaceInfo info = (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
  +                targetElement, null, -1, false);
  +        if(null != info)
  +          return info.getShouldStripSpace();
  +          
  +        Node parent = targetElement.getParentNode();
  +        if(null != parent && Node.ELEMENT_NODE == parent.getNodeType())
  +          targetElement = (Element)parent;
  +        else
  +          targetElement = null;
  +      }
  +    }
  +    return false;
  +  }
  +  
  +  /**
  +   * Get information about whether or not whitespace can be stripped.
  +   * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
  +   *
  +   * @return true if the whitespace can be stripped.
  +   */
  +  public boolean canStripWhiteSpace()
  +  {
  +    return (null != m_whiteSpaceInfoList);
  +  }
  +  
  +
   
     /**
      * <meta name="usage" content="advanced"/>
  
  
  
  1.3       +21 -0     xml-xalan/java/src/org/apache/xml/utils/XMLCharacterRecognizer.java
  
  Index: XMLCharacterRecognizer.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/utils/XMLCharacterRecognizer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLCharacterRecognizer.java	2000/12/01 20:30:16	1.2
  +++ XMLCharacterRecognizer.java	2001/01/04 08:06:23	1.3
  @@ -118,4 +118,25 @@
   
       return true;
     }
  +  
  +  /**
  +   * Tell if the string is whitespace.
  +   *
  +   * @param buf StringBuffer to check as XML whitespace.
  +   * @return True if characters in buffer are XML whitespace, false otherwise
  +   */
  +  public static boolean isWhiteSpace(String s)
  +  {
  +
  +    int n = s.length();
  +
  +    for (int i = 0; i < n; i++)
  +    {
  +      if (!isWhiteSpace(s.charAt(i)))
  +        return false;
  +    }
  +
  +    return true;
  +  }
  +
   }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xpath/WhitespaceStrippingElementMatcher.java
  
  Index: WhitespaceStrippingElementMatcher.java
  ===================================================================
  package org.apache.xpath;
  
  import org.w3c.dom.Element;
  import javax.xml.transform.TransformerException;
  
  /**
   * A class that implements this interface can tell if a given element should 
   * strip whitespace nodes from it's children.
   */
  public interface WhitespaceStrippingElementMatcher
  {
    /**
     * Get information about whether or not an element should strip whitespace.
     * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
     *
     * @param support The XPath runtime state.
     * @param targetElement Element to check
     *
     * @return true if the whitespace should be stripped.
     *
     * @throws TransformerException
     */
    public boolean shouldStripWhiteSpace(
            XPathContext support, Element targetElement) throws TransformerException;
    
    /**
     * Get information about whether or not whitespace can be stripped.
     * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT Specification</a>
     *
     * @return true if the whitespace can be stripped.
     */
    public boolean canStripWhiteSpace();
  }
  
  
  1.6       +64 -8     xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java
  
  Index: ChildIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ChildIterator.java	2001/01/02 03:47:14	1.5
  +++ ChildIterator.java	2001/01/04 08:06:24	1.6
  @@ -59,14 +59,17 @@
   import javax.xml.transform.TransformerException;
   
   import org.apache.xpath.compiler.Compiler;
  +import org.apache.xpath.patterns.NodeTest;
  +import org.apache.xpath.WhitespaceStrippingElementMatcher;
  +import org.apache.xml.utils.PrefixResolver;
   
   import org.w3c.dom.Node;
   import org.w3c.dom.DOMException;
   
   /**
    * <meta name="usage" content="advanced"/>
  - * This class implements an optimized iterator for 
  - * "node()" patterns, that is, any children of the 
  + * This class implements an optimized iterator for
  + * "node()" patterns, that is, any children of the
    * context node.
    * @see org.apache.xpath.axes.WalkerFactory#newLocPathIterator
    */
  @@ -77,8 +80,9 @@
      * Create a ChildIterator object.
      *
      * @param compiler A reference to the Compiler that contains the op map.
  -   * @param opPos The position within the op map, which contains the 
  +   * @param opPos The position within the op map, which contains the
      * location path expression for this itterator.
  +   * NEEDSDOC @param analysis
      *
      * @throws javax.xml.transform.TransformerException
      */
  @@ -92,10 +96,10 @@
      *  Returns the next node in the set and advances the position of the
      * iterator in the set. After a NodeIterator is created, the first call
      * to nextNode() returns the first node in the set.
  -   * 
  +   *
      * @return  The next <code>Node</code> in the set being iterated over, or
      *   <code>null</code> if there are no more members in that set.
  -   * 
  +   *
      * @throws DOMException
      *    INVALID_STATE_ERR: Raised if this method is called after the
      *   <code>detach</code> method was invoked.
  @@ -120,10 +124,62 @@
   
       Node next;
   
  -    m_lastFetched = next = (null == m_lastFetched)
  -                           ? m_context.getFirstChild()
  -                           : m_lastFetched.getNextSibling();
  +    while (true)
  +    {
  +      m_lastFetched = next = (null == m_lastFetched)
  +                             ? m_context.getFirstChild()
  +                             : m_lastFetched.getNextSibling();
  +
  +      // Yuck!  Blech!  -sb
  +      if (null != next)
  +      {
  +        int nt = next.getNodeType();
  +        if(Node.DOCUMENT_TYPE_NODE == nt) // bug fix, position14, d2d, xerces DOM
  +          continue;
  +        else if ((Node.TEXT_NODE == nt)
  +                &&!next.isSupported(SUPPORTS_PRE_STRIPPING, null))
  +        {
  +          Node parent = next.getParentNode();
  +
  +          if (null != parent && Node.ELEMENT_NODE == parent.getNodeType())
  +          {
  +            String data = next.getNodeValue();
  +
  +            if (org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(
  +                    data))
  +            {
  +
  +              // Ugly trick for now.
  +              PrefixResolver resolver =
  +                getXPathContext().getNamespaceContext();
  +
  +              if (resolver instanceof WhitespaceStrippingElementMatcher)
  +              {
  +                WhitespaceStrippingElementMatcher wsem =
  +                  (WhitespaceStrippingElementMatcher) resolver;
  +
  +                try
  +                {
  +                  if (wsem.shouldStripWhiteSpace(
  +                          getXPathContext(), (org.w3c.dom.Element) parent))
  +                  {
  +                    continue;
  +                  }
  +                }
  +                catch (javax.xml.transform.TransformerException te)
  +                {
  +                  throw new org.apache.xml.utils.WrappedRuntimeException(te);
  +                }
  +              }
  +            }
  +          }
  +        }
  +      }
  +
  +      break;
  +    }
   
  +    // m_lastFetched = next;
       if (null != next)
       {
         if (null != m_cachedNodes)
  
  
  
  1.17      +32 -1     xml-xalan/java/src/org/apache/xpath/patterns/NodeTest.java
  
  Index: NodeTest.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/patterns/NodeTest.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- NodeTest.java	2001/01/02 03:47:18	1.16
  +++ NodeTest.java	2001/01/04 08:06:24	1.17
  @@ -65,6 +65,8 @@
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.objects.XNumber;
   import org.apache.xpath.objects.XObject;
  +import org.apache.xpath.WhitespaceStrippingElementMatcher;
  +import org.apache.xml.utils.PrefixResolver;
   
   import org.w3c.dom.Node;
   import org.w3c.dom.traversal.NodeFilter;
  @@ -80,6 +82,11 @@
     /** The namespace or local name for node tests with a wildcard.
      *  @see <a href="http://www.w3.org/TR/xpath#NT-NameTest">the XPath NameTest production.</a> */
     public static final String WILD = "*";
  +  
  +  /** The URL to pass to the Node#supports method, to see if the 
  +   * DOM has already been stripped of whitespace nodes. */
  +  public static final String SUPPORTS_PRE_STRIPPING =
  +    "http://xml.apache.org/xpath/features/whitespace-pre-stripping";
   
     /**
      * This attribute determines which node types are accepted.
  @@ -373,11 +380,35 @@
     public XObject execute(XPathContext xctxt, Node context)
             throws javax.xml.transform.TransformerException
     {
  +    short nodeType = context.getNodeType();
  +    
  +    // Yuck!  Blech!  -sb
  +    if(Node.TEXT_NODE == nodeType && !context.isSupported(SUPPORTS_PRE_STRIPPING, null))
  +    {
  +      Node parent = context.getParentNode();
  +      if(null != parent && Node.ELEMENT_NODE == parent.getNodeType())
  +      {
  +        String data = context.getNodeValue();
  +        if(org.apache.xml.utils.XMLCharacterRecognizer.isWhiteSpace(data))
  +        {
  +          // Ugly trick for now.
  +          PrefixResolver resolver = xctxt.getNamespaceContext();
  +          if(resolver instanceof WhitespaceStrippingElementMatcher)
  +          {
  +            WhitespaceStrippingElementMatcher wsem = 
  +               (WhitespaceStrippingElementMatcher)resolver;
  +            if(wsem.shouldStripWhiteSpace(xctxt, (org.w3c.dom.Element)parent))
  +            {
  +              return SCORE_NONE;
  +            }
  +          }
  +        }
  +      }
  +    }
   
       if (m_whatToShow == NodeFilter.SHOW_ALL)
         return m_score;
   
  -    short nodeType = context.getNodeType();
       int nodeBit = (m_whatToShow & (0x00000001 << (nodeType - 1)));
   
       switch (nodeBit)