Package Torello.HTML

Class Attributes


  • public class Attributes
    extends java.lang.Object
    Utilities for getting, setting and removing attributes from the TagNode elements in a Web-Page Vector.

    This class is used to perform iteration-loops over HTML Element Vectors where each and every TagNode Attribute can be updated, modified, added or removed with just a single method invocation. This class can be used in conjunction with the 'AUM' enumerated-type class where the type of updated is refined/specified.

    It is important to note that these methods are really just for-loops that update an html-page with nodes whose attributes have changed. Generally, the methods in this class will not save a lot of typing - since the for-loop is not very long and replacing old HTML Elements with new ones in a Vector should be easy. However, with error checking, exception reporting and String-concatenation provided by the enum 'AUM' (Attribute Update Mode) enumerated-type - the value of using this class over a simple for loop becomes more apparent: less error-prone & simpler code.

    "Re-Inventing the Wheel' is something that happens in American Computer-Programming circles pretty easily. C#, for instance, but before getting into complaints about software system engineering, it should be pointed out that this class (class Attributes) along with enum AUM - when working together - behave similarly to the pair: class ReplaceNodes and class ReplaceFunction. Both of these are generally used to replace HTML TagNode's in a vectorized-html web-page with ones that have updated attributes.
    See Also:
    AUM


Stateless Class: This class neither contains any program-state, nor can it be instantiated. The @StaticFunctional Annotation may also be called 'The Spaghetti Report'. Static-Functional classes are, essentially, C-Styled Files, without any constructors or non-static member field. It is very similar to the Java-Bean @Stateless Annotation.
  • 1 Constructor(s), 1 declared private, zero-argument constructor
  • 32 Method(s), 32 declared static
  • 0 Field(s)


    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class
      static interface  Attributes.Filter
    • Method Summary

       
      Retrieve the Attributes inside all of the TagNode's, Contained by a Vector
      Modifier and Type Method
      static Ret2<int[],​String[]> retrieve​(Vector<? super TagNode> html, String attribute)
       
      Retrieve the Attributes of a Vector's TagNode's, Range-Limited
      Modifier and Type Method
      static String[] retrieve​(Vector<? super TagNode> html, int[] posArr, String attribute)
      static Ret2<int[],​String[]> retrieve​(Vector<? super TagNode> html, int sPos, int ePos, String attribute)
      static Ret2<int[],​String[]> retrieve​(Vector<? super TagNode> html, DotPair dp, String attribute)
       
      Remove some, or all, of the Attribute from all of the TagNode's, Contained by a Vector
      Modifier and Type Method
      static int[] filter​(Vector<? super TagNode> html, String... innerTagWhiteList)
      static int[] filter​(Vector<? super TagNode> html, StrFilter filter)
      static int[] remove​(Vector<? super TagNode> html, String... innerTags)
      static int[] removeAll​(Vector<? super TagNode> html)
      static int[] removeData​(Vector<? super TagNode> html)
       
      Remove some, or all, of the Attributes of a Vector's TagNode's, Range-Limited: sPos & ePos
      Modifier and Type Method
      static int[] filter​(Vector<? super TagNode> html, int sPos, int ePos, String... innerTagWhiteList)
      static int[] filter​(Vector<? super TagNode> html, int sPos, int ePos, StrFilter filter)
      static int[] remove​(Vector<? super TagNode> html, int sPos, int ePos, String... innerTags)
      static int[] removeAll​(Vector<? super TagNode> html, int sPos, int ePos)
      static int[] removeData​(Vector<? super TagNode> html, int sPos, int ePos)
       
      Remove some, or all, of the Attributes of a Vector's TagNode's, Range-Limited: DotPair
      Modifier and Type Method
      static int[] filter​(Vector<? super TagNode> html, DotPair dp, String... innerTagWhiteList)
      static int[] filter​(Vector<? super TagNode> html, DotPair dp, StrFilter filter)
      static int[] remove​(Vector<? super TagNode> html, DotPair dp, String... innerTags)
      static int[] removeAll​(Vector<? super TagNode> html, DotPair dp)
      static int[] removeData​(Vector<? super TagNode> html, DotPair dp)
       
      Remove some, or all, of the Attributes of a Vector's TagNode's, Range-Limited: Index-Position Array
      Modifier and Type Method
      static int[] filter​(Vector<? super TagNode> html, int[] posArr, String... innerTagWhiteList)
      static int[] filter​(Vector<? super TagNode> html, int[] posArr, StrFilter filter)
      static int[] remove​(Vector<? super TagNode> html, int[] posArr, String... innerTags)
      static int[] removeAll​(Vector<? super TagNode> html, int[] posArr)
      static int[] removeData​(Vector<? super TagNode> html, int[] posArr)
       
      Modify the Attributes inside all of the TagNode's, Contained by a Vector
      Modifier and Type Method
      static int[] update​(Vector<? super TagNode> html, Attributes.Filter f)
      static int[] update​(Vector<? super TagNode> html, AUM mode, String innerTag, String itValue, SD quote)
       
      Modify the Attributes of a Vector's TagNode's, Range-Limited: sPos & ePos
      Modifier and Type Method
      static int[] update​(Vector<? super TagNode> html, int sPos, int ePos, Attributes.Filter f)
      static int[] update​(Vector<? super TagNode> html, AUM mode, int sPos, int ePos, String innerTag, String itValue, SD quote)
       
      Modify the Attributes of a Vector's TagNode's, Range-Limited: DotPair
      Modifier and Type Method
      static int[] update​(Vector<? super TagNode> html, AUM mode, DotPair dp, String innerTag, String itValue, SD quote)
      static int[] update​(Vector<? super TagNode> html, DotPair dp, Attributes.Filter f)
       
      Modify the Attributes of a Vector's TagNode's, Range-Limited: Index-Position Array
      Modifier and Type Method
      static int[] update​(Vector<? super TagNode> html, int[] posArr, Attributes.Filter f)
      static int[] update​(Vector<? super TagNode> html, AUM mode, int[] posArr, String innerTag, String itValue, SD quote)
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • update

        🡅  🡇    
        public static int[] update​(java.util.Vector<? super TagNode> html,
                                   AUM mode,
                                   int sPos,
                                   int ePos,
                                   java.lang.String innerTag,
                                   java.lang.String itValue,
                                   SD quote)
        Will update any HTML TagNode's present in the vector-parameter 'html' according to passed AUM mode and the 'innerTag' parameter.

        NOTE: This method restricts the update process to the specified subrange sPos ... ePos of the 'html' Vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        mode - Since the purpose of this class is to update, modify, or remove HTML Element Inner-Tag key-value pairs, the mechanism - or the desired behavior - of the update process needs to be specified. Use the enumerated type enum 'AUM'. for choosing what update type is needed.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        innerTag - This is the name of the HTML attribute that needs to be changed, added, or removed.
        itValue - This is the value that the attribute needs to be set, or removed, depending upon which of the AUM modes is selected. If AUM.RemoveSubString were chosen, then all HTML Elements within the specified Vector range would have the first copy of 'itValue' removed from any TagNode's containing an attribute with name 'innerTag'.
        quote - The programmer is expected to select either SD.Single-Quote or SD.Double-Quote. The updated Attribute / Inner-Tag key-value pairs will be surrounded by the selected quote. Always remember that the class 'TagNode' checks for quotes-within-quotes, and will throw an exception if two-double quotes also contain a double-quote within the inner-tag value, or vice-versa (single-quotes within a two single-quoted attribute-value).
        Returns:
        This method shall return an integer-array index-list whose values identify which HTML Vector Elements were changed as a result of this method invocation.

        NOTE: One minor subtlety, there could be cases where a new HTML Element 'TagNode' reference / object were instantiated or 'created,' even though the actual String that comprised the HTMLNode itself were identical to the original HTMLNode.str String. In the 'AUM' enumerated-type, when AUM.Set is invoked, the original String data for an attribute is always clobbered, even in cases where an identical version of the String is replaced or substituted.
        Throws:
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the attribute key-value pairs have a quotation-choice such that the chosen quotation-mark is also found within the attribute-value.

        QuotesException will also throw in the case that an attribute key-value pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        InnerTagKeyException - This exception will throw if a non-standard String-value is passed to parameter String 'innerTag'. HTML expects that an attribute-name conform to a set of rules in order to be processed by a browser.
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        AUM.update(TagNode, String, String, SD), LV, TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         InnerTagKeyException.check(innerTag);
        
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // This optimization is the same as the one in TagNode.openTagPWA().  However, that method
         // cannot be used here, becaue for AUM.set, zero-attribute TagNode's **ALSO** have to be
         // updated.  So this is re-implemented here.
         int MIN = 3 + innerTag.length();
        
         // Loop Variables
         LV      l   = new LV(sPos, ePos, html);
         TagNode tn;
        
         for (int i=l.start; i < l.end; i++)
        
             // Only instances of Opening-TagNodes need to be checked - All others should be skipped
             if ((tn = ((HTMLNode) html.elementAt(i)).openTag()) != null)
        
                 // AUM.Set does not require the attribute to already exist
                 // **OR** Check for minimum possible str-length to have the attribute at all.
                 if ((mode == AUM.Set) || (tn.str.length() >= (MIN + tn.tok.length())))  
        
                     // If AUM.update returns a **NEW** (non-null) TagNode, replace the old one.
                     if ((tn = mode.update(tn, innerTag, itValue, quote)) != null)
                     {
                         // Replace the old TagNode
                         html.setElementAt(tn, i);
        
                         // Make sure to keep the index where it resides, to return to the user
                         b.accept(i);
                     }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • update

        🡅  🡇    
        public static int[] update​(java.util.Vector<? super TagNode> html,
                                   AUM mode,
                                   int[] posArr,
                                   java.lang.String innerTag,
                                   java.lang.String itValue,
                                   SD quote)
        Will update any HTML TagNode's present in the vector-parameter 'html' according to a passed 'AUM' mode and the 'innerTag' parameter.

        NOTE: This method restricts the removal process to only nodes specified by the Vector-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        mode - Since the purpose of this class is to update, modify, or remove HTML Element Inner-Tag key-value pairs, the mechanism - or the desired behavior - of the update process needs to be specified. Use the enumerated type enum 'AUM'. for choosing what update type is needed.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Paragraph Element.
         int[] posArr = TagNodeFind.all(htmlPage, TC.OpeningTags, "p");
        
         // This line will ensure that every HTML Paragraph Element that was found on the HTML
         // page in the previous line of code - shall have a CSS class='MyClass' key-value
         // Inner-Tag.  The returned array will contain a list of pointers to HTML Paragraph 
         // Elements that were changed.
         
         int[] changedPosArr = Attributes.update
              (htmlPage, AUM.set, posArr, "class", "MyClass", SD.SingleQuote);
        
        innerTag - This is the name of the HMTL attribute that needs to be changed, added, or removed.
        itValue - This is the value that the attribute needs to be set, or removed, depending upon which of the AUM modes is selected. If AUM.RemoveSubString were chosen, then all HTML Elements within the specified Vector range would have the first copy of 'itValue' removed from any HTML containing an attribute with name 'innerTag'.
        quote - The programmer is expected to select either SD.Single-Quote or SD.Double-Quote. The updated Attribute / Inner-Tag key-value pairs will be surrounded by the selected quote. Always remember that the class 'TagNode' checks for quotes-within-quotes, and will throw an exception if two-double quotes also contain a double-quote within the inner-tag value, or vice-versa (single-quotes within a two single-quoted attribute-value).
        Returns:
        This method shall return an integer-array index-list whose values identify which HTML Vector Elements were changed as a result of this method invokation.

        NOTE: One minor subtlety, there could be cases where a new HTML Element 'TagNode' reference / object were instantiated or 'created,' even though the actual String that comprised the HTMLNode itself were identical to the original HTMLNode.str String. In the 'AUM' enumerated-type, when AUM.Set is invoked, the original String data for an attribute is always clobbered, even in cases where an identical version of the String is replaced or substituted.
        Throws:
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the attribute key-value pairs have a quotation-choice such that the chosen quotation-mark is also found within the attribute-value.

        QuotesException will also throw in the case that an attribute key-value pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        InnerTagKeyException - This exception will throw if a non-standard String-value is passed to parameter String 'innerTag'. HTML expects that an attribute-name conform to a set of rules in order to be processed by a browser.
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        AUM.update(TagNode, String, String, SD), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         InnerTagKeyException.check(innerTag);
        
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // minimum possible length to have an attribute at all.
         // '<', TOKEN, SPACE, ATTRIBUTE, '>'
        
         int MIN = 3 + innerTag.length();
        
         for (int i : posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i); 
        
             if (! n.isTagNode())  throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // AUM.Set *DOES NOT* require the attribute to exist already (the other *DO*)
             if (mode != AUM.Set)
        
                 // Minimum length of this element before it even could have the named inner-tag
                 // '<', TOKEN, SPACE, ATTRIBUTE, '=', '>'
        
                 if (tn.str.length() < (MIN + tn.tok.length())) continue;
        
             tn = mode.update(tn, innerTag, itValue, quote);
        
             // if 'tn' is non-null ==> an update *WAS* performed
             if (tn != null)
             {
                 // Replace the old TagNode
                 html.setElementAt(tn, i);
        
                 // Make sure to keep the index where it resides, to return to the user
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
          return b.build().toArray();
        
      • removeAll

        🡅  🡇    
        public static int[] removeAll​(java.util.Vector<? super TagNode> html,
                                      int sPos,
                                      int ePos)
        The purpose of this method is to remove all attributes / Inner-Tag key-value pairs from each and every non-'TextNode' and non-'CommentNode' HTML Element found on the vectorized-html page parameter 'html'. The removal process is limited to the range specified by method-parameters sPos, ePos.

        Specifically: Each and every class=... id=... src=... alt=... href=... onclick=... etc... attribute from each and every instance of 'TagNode' HTML Element found in the vectorized-page parameter 'html' (and whose index-location falls between 'sPos' and ) will be removed. All TagNode's, in the specified range, shall be attribute-free.

        AGAIN: This method restricts the removal process to the specified subrange sPos ... ePos of the HTML-Vector.

        Example:
         // Retrieve the contents from the foreign news source "https://www.gov.cn" - pick an article
         
         URL              url     = new URL("http://www.gov.cn/premier/2020-xx/xx/content_55267.htm");
         Vector<HTMLNode> news    = HTMLPage.getPageTokens(url, false);
         
         // Now retrieve the "article body"
         Vector<HTMLNode> body = InnerTagGetInclusive.first
             (page, "div", "class", TextComparitor.C, "article");
         
         // To view a "pared down" version - with all CSS class, id information removed - call this
         // method, and only the raw HTML tags will remain... <P>, <DIV>, <B>... etc.
         // Passing 0 and -1 means the 'entire-page' is processed.
         Attributes.removeAll(body, 0, -1);
         
         // Print the updated "article body" Vector using the Debug class.  It should be MUCH EASIER
         // to read.
         //
         // AGAIN: all long-winded "class" "ID" and other common HTML clutter has been removed.
         
         System.out.println(Util.pageToString(body));
        
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer array of 'Vector'-index positions of each and every HTML Element 'TagNode' whose attributes were removed.
        Throws:
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        TagNode.removeAllAV(), TagNode.isTagNode(), TagNode.isClosing, LV
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // Loop Variables
         LV      l = new LV(sPos, ePos, html);
         TagNode tn;
        
         for (int i=l.start; i < l.end; i++)
        
             // REQUIREMENTS: Only Opening-TagNodes
             // If element-length = tok-length+2, there are no attributes: '<', TOKEN, '>'
        
             if ((tn = ((HTMLNode) html.elementAt(i)).openTag()) != null)
        
                 if (tn.str.length() > (tn.tok.length() + 2))
                 {
                     // Replace the old TagNode
                     html.setElementAt(tn.removeAllAV(), i);
        
                     // Make sure to keep the index where it resides, to return to the user
                     b.accept(i);
                 }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • removeAll

        🡅  🡇    
        public static int[] removeAll​(java.util.Vector<? super TagNode> html,
                                      int[] posArr)
        The purpose of this method is to remove all attributes / Inner-Tag key-value pairs from each and every non-'TextNode' and non-'CommentNode' HTML Element found on the vectorized-html page parameter 'html'. The removal process is limited to the only removing attributes from elements pointed to by the contents of passed-parameter 'posArr'

        Specifically: Each and every class=... id=... src=... alt=... href=... onclick=... etc... attribute from each and every instance of 'TagNode' HTML Element specified by the 'posArr' index-list will be removed. Afterwards, all TagNode's, that were pointed to be the input-parameter 'posArr' shall be completely attribute-free.

        AGAIN: This method restricts the removal process to only nodes specified by the 'Vector'-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Paragraph Element.
         int[] posArr         = TagNodeFind.all(htmlPage, TC.OpeningTags, "p");
        
         // This line will remove every attribute key-value pair from every HTML Paragraph
         // Element on the vectorized-html page 'htmlPage'
         // The returned array will contain a list of pointers to HTML Paragraph Elements that
         // were changed.  Paragraph Elements that were already empty of Inner-Tag key-value pairs
         // will not have a pointer in this index-array.
         int[] changedPosArr  = Attributes.removeAll(htmlPage, posArr);
        
        Returns:
        An integer array of 'Vector'-index positions of each and every HTML Element 'TagNode' which has had its attributes removed by this method.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        TagNode.removeAllAV(), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         for (int i : posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // If element-length = tok-length+2, there are no attributes!
             // Otherwise, replace the old TagNode with a new, empty, one
             // Make sure to keep the index where it resides, to return to the user
        
             if (tn.str.length() > (tn.tok.length() + 2))
             {                                                   
                 html.setElementAt(tn.removeAllAV(), i);
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • removeData

        🡅  🡇    
        public static int[] removeData​(java.util.Vector<? super TagNode> html,
                                       int sPos,
                                       int ePos)
        The purpose of this method is to remove all HTML data-attribute key-value pairs from 'TagNode' Elements contained inside parameter 'html'.

        NOTE: This method restricts the removal process to only the nodes inside the specified subrange sPos ... ePos of input-parameter 'html'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer array of 'Vector'-index positions of each and every HTML Element 'TagNode' which did contain HTML data-attributes that have since been removed.
        Throws:
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        TagNode.removeDataAttributes(), TagNode.isTagNode(), TagNode.isClosing, LV
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // Loop Counter & Temporary Variables
         LV      l   = new LV(sPos, ePos, html);
         TagNode tn, newTN;
        
         for (int i=l.start; i < l.end; i++)
        
             // Only instances of Opening-TagNodes, possibly with attributes
             if ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null)
        
                 // A "new" TagNode is *only returned* if the "data-attributes" were removed.
                 if ((newTN = tn.removeDataAttributes()) != tn)
                 {                                                   
                     html.setElementAt(newTN, i);    // Replace the old TagNode
                     b.accept(i);                    // Make sure to keep the index where it resides
                 }                                   // Method returns list of modified node's
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • removeData

        🡅  🡇    
        public static int[] removeData​(java.util.Vector<? super TagNode> html,
                                       int[] posArr)
        The purpose of this method is to remove all HTML data-attribute key-value pairs from 'TagNode' Elements contained inside parameter 'html'.

        NOTE: This method restricts the removal process to only the nodes which are specified by 'Vector'-index array-parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Image Element.
         int[] posArr         = TagNodeFind.all(htmlPage, TC.OpeningTags, "img");
        
         // This line will remove every "data-attribute" key-value pair from every HTML Image
         // Element on the vectorized-html page 'htmlPage'
         // The returned array will contain a list of pointers to HTML Paragraph Elements that
         // were changed.  Image Elements that did not have "data-" HTML InnerTags
         // will not have a pointer in this index-array.
         int[] changedPosArr  = Attributes.removeData(htmlPage, posArr);
        
        Returns:
        An integer array of 'Vector'-index positions of each and every HTML Element 'TagNode' whose data attributes removed.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        TagNode.removeDataAttributes(), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // Minimum Length of TagNode.str to even have a "data-*=" attribute
         // '<', HTML-TOKEN, SPACE, "data-*", '>'
         int MIN = 9;
        
         for (int i: posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // Minimum Length of TagNode.str to even have a "data-*=" attribute
             if (tn.str.length() < (tn.tok.length() + MIN)) continue;
        
             TagNode newTN = tn.removeDataAttributes();
        
             // A "new" TagNode is *only returned* by this method if the "data-attributes" were
             // removed.  If new, replace the old TagNode
             if (newTN != tn)
             {                    
                 html.setElementAt(newTN, i);
                 b.accept(i); // Make sure to keep the index where it resides, to return to the user
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • remove

        🡅  🡇    
        public static int[] remove​(java.util.Vector<? super TagNode> html,
                                   int sPos,
                                   int ePos,
                                   java.lang.String... innerTags)
        This will remove all copies of the attributes whose names are listed among the by String[] array parameter 'innerTags' from the vectorized-html web-page parameter 'html'.

        NOTE: This method restricts the removal process to the specified subrange sPos ... ePos of the 'html' vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        innerTags - This String, or list of String's, should contain valid HTML Element inner-tag names. Any instances of these attributes which are found inside HTML TagNode's on the web-page Vector will be removed from the TagNode, and the old TagNode will be replaced in the vectorized-html web-page with a new, pared-down, TagNode.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements in which the key-value pairs which were requested be removed by this method, have been removed.
        Throws:
        InnerTagKeyException - This exception will throw if a non-standard String-value is passed to parameter String 'innerTag'. HTML expects that an attribute-name conform to a set of rules in order to be processed by a browser.
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        java.lang.IllegalArgumentException - If parameter 'innerTags' has zero elements.
        See Also:
        TagNode.removeAttributes(String[]), LV, TagNode.hasOR(boolean, String[]), TagNode.isTagNode(), TagNode.isClosing, InnerTagKeyException.check(String[])
        Code:
        Exact Method Body:
         InnerTagKeyException.check(innerTags);
        
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // Loop Counter & Temporary Variables
         LV      l   = new LV(sPos, ePos, html);
         TagNode tn;
        
         for (int i=l.start; i < l.end; i++)
        
             // Only instances of Opening-TagNodes, possibly with attributes
             if ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null)
        
                 // If this TagNode has the attributes that have been requested for removal, then...
                 if (tn.hasOR(false, innerTags))
                 {
                     // Build a new TagNode, and then replace the old one with the newly built one
                     // on the page or sub-page, and at the same location.
                     tn = tn.removeAttributes(innerTags);
                     html.setElementAt(tn, i);
        
                     // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                     // At the end of this method, the list will be built and returned to the user.
                     // It shall contain all Vector locations where a "TagNode swap" (replaced
                     // TagNode, with attributes filtered) has occurred.
                     b.accept(i);
                 }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • remove

        🡅  🡇    
        public static int[] remove​(java.util.Vector<? super TagNode> html,
                                   int[] posArr,
                                   java.lang.String... innerTags)
        This will remove all copies of the attributes whose names are listed among the by String[] array parameter 'innerTags' from the vectorized-html web-page parameter 'html'.

        NOTE: This method restricts the removal process to only nodes specified by the 'Vector'-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        innerTags - This String, or list of String's, should contain valid HTML Element inner-tag names. Any instances of these attributes which are found inside HTML TagNode's on the web-page Vector will be removed from the TagNode, and the old TagNode will be replaced in the vectorized-html web-page with a new, pared-down, TagNode.

        AGAIN: This method shall only modify TagNode's if their Vector-index locations in 'html' are listed in 'posArr'.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Paragraph Element.
         int[] posArr         = TagNodeFind.all(htmlPage, TC.OpeningTags, "p");
        
         // This line will remove attribute key-value pairs for 'class' and 'id' from every HTML 
         // Paragraph Element on the vectorized-html page 'htmlPage.'  The returned array will 
         // contain a list of pointers to HTML Paragraph Elements that were changed.  Paragraph
         // Elements that did not contain a 'class' nor an 'id' inner-tag will not have a pointer 
         // in the returned index-array, and therefore will not have been modified.
         int[] changedPosArr  = Attributes.remove(htmlPage, posArr, "class", "id");
        
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements in which the key-value pairs which were requested be removed by this method, have been removed.
        Throws:
        InnerTagKeyException - This exception will throw if a non-standard String-value is passed to parameter String 'innerTag'. HTML expects that an attribute-name conform to a set of rules in order to be processed by a browser.
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        java.lang.IllegalArgumentException - If parameter 'innerTags' has zero elements.
        See Also:
        TagNode.removeAttributes(String[]), TagNode.hasOR(boolean, String[]), TagNode.isTagNode(), TagNode.isClosing, InnerTagKeyException.check(String[])
        Code:
        Exact Method Body:
         InnerTagKeyException.check(innerTags);
        
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         // Compute the "minimum length" of a TagNode.str field
         int MIN = 1000;
        
         // Minimum-Length of TagNode.str would have to be 3 + smallest inner-tag passed
         for (String attrib : innerTags) if (attrib.length() < MIN) MIN = attrib.length();
         MIN += 3;
        
         for (int i : posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // If element-length <= MIN, none of the attributes could possibly be present.
             if (tn.str.length() < (tn.tok.length() + MIN)) continue;
        
             // If this TagNode has the attributes that have been requested for removal, then...
             if (tn.hasOR(false, innerTags))
             {
                 // Build a new TagNode, and then replace the old one with the newly built one
                 // on the page or sub-page, and at the same location.
                 tn = tn.removeAttributes(innerTags);
                 html.setElementAt(tn, i);
        
                 // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                 // At the end of this method, the list will be built and returned to the user.
                 // It shall contain all Vector locations where a "TagNode swap" (replaced
                 // TagNode, with attributes filtered) has occurred.
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • retrieve

        🡅  🡇    
        public static Ret2<int[],​java.lang.String[]> retrieve​
                    (java.util.Vector<? super TagNode> html,
                     int sPos,
                     int ePos,
                     java.lang.String attribute)
        
        The purpose of this method is to retrieve the value of each attribute in each TagNode in an HTML Vector (or sub-Vector) that contained such an attribute.

        NOTE: This method restricts the retrieval process to the specified subrange sPos ... ePos of the HTML-Vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? extends HTMLNode' means is this method can receive a Vector<TagNode>, Vector<TextNode> or a Vector<CommentNode>, without throwing an exception, or producing erroneous results. These 'sub-type' Vectors are very often returned as search results from the classes in the 'NodeSearch' package. The most common vector-type used is Vector<HTMLNode>.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        attribute - This is the HTML attribute-value that is being retrieved. Each instance of TagNode in the input 'html' parameter Vector shall be searched for this attribute-name. If this attribute is present in any of the TagNode's in HTML, then that TagNode's location (Vector-index) shall be returned in the int[] position array, and the value of that attribute shall be returned in the String[] array.
        Returns:
        An instance of Ret2<int[], String[]> where the two return-fields are as follows:

        • Ret2.a (int[])

          This an integer-array int[] containing the indices of each instance of TagNode that contained a non-null attribute matching parameter 'attribute'.

        • Ret2.b (String[])

          This a String-array String[] containing the values of the attributes in the TagNode's that contained the named 'attribute'.


        NOTE: These arrays should be considered parallel arrays.

        ALSO: This method shall never return null, if there are no matches, an instance of Ret2<int[], String[]> shall be returned, containing zero length arrays.
        Throws:
        InnerTagKeyException - If the attribute name passed to this parameter does not contain the name of a valid HTML5 attribute, then this exception shall throw.
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        TagNode.AV(String), TagNode.isTagNode(), TagNode.isClosing, InnerTagKeyException.check(String[]), LV
        Code:
        Exact Method Body:
         InnerTagKeyException.check(attribute);
        
         // Use a Java Int-Stream.  Save matches here (vector-position)
         IntStream.Builder posB = IntStream.builder();
        
         // Use a Java Stream<String>.  Save attribute-values here
         Stream.Builder<String> strB = Stream.builder();
        
         // Temp Variables & Loop Variable
         LV      l = new LV(sPos, ePos, html);
         TagNode tn;
         String  attribValue;
        
         for (int i=l.start; i < l.end; i++)
        
             // Only Visit Open TagNode Elements with '.str' long enough to contain attributes
             if ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null)
        
                 // If the Open-Tag does not have the attribute, skip the node. If it does, save it.
                 if ((attribValue = tn.AV(attribute)) != null)
                 { 
                     posB.accept(i);             // Save the vector-index position of the TagNode
                     strB.accept(attribValue);   // Save the Attribute-Value inside that TagNode
                 }
        
         // Java Stream's shall build the arrays.  Put them into an instance of Ret2, and return
         return new Ret2<>(posB.build().toArray(), strB.build().toArray(String[]::new));
        
      • retrieve

        🡅  🡇    
        public static java.lang.String[] retrieve​
                    (java.util.Vector<? super TagNode> html,
                     int[] posArr,
                     java.lang.String attribute)
        
        This shall query each element listed in the position-array (parameter 'posArr') for the value of the attribute of the HTML Element located at these positions. The value of each attribute will be appended to a parallel String-array and returned. This String[] array shall be parallel to the input Vector-index 'posArr' parameter.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? extends HTMLNode' means is this method can receive a Vector<TagNode>, Vector<TextNode> or a Vector<CommentNode>, without throwing an exception, or producing erroneous results. These 'sub-type' Vectors are very often returned as search results from the classes in the 'NodeSearch' package. The most common vector-type used is Vector<HTMLNode>.
        posArr - This shall be a list of Vector-indices that contain opening TagNode elements. The value of the attribute provided by parameter 'attribute' will be returned in a parallel String[] array for each TagNode identified by 'posArr'.
        attribute - This is the name of the HTML attribute that is being retrieved. Each TagNode element at the locations specified by input parameter 'posArr' shall be searched for this attribute (name), and the value of that attribute shall be placed in the returned String[] array.

        If any of the TagNode instances listed by the Vector-index array do not have that attribute, then a 'null' shall be placed in the returned String[] array at the index-location parallel to its position in 'posArr'
        Returns:
        This returns a String[] array that shall be parallel to the input-parameter int[] posArr. Each location in this String-array shall correspond to the attribute-value returned by a call to TagNode.AV(attribute) on the TagNode that is located at the Vector-index identified by the value at 'posArr'.
        Throws:
        InnerTagKeyException - If the String provided to parameter 'attribute' is not a valid HTML-5 attribute-name, then this exception shall thow.
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        InnerTagKeyException.check(String[]), TagNode.AV(String), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         InnerTagKeyException.check(attribute);
        
         // Return Array, and its corresponding array-index pointer.
         String[]    ret = new String[posArr.length];
         int         i   = 0;
        
         // Minimum length of the TagNode.str to even have the specified attribute
         // '<', TOKEN, SPACE, INNERTAG, '=', '>'
         int MIN = 4 + attribute.length();
        
         for (int pos: posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(pos);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(pos);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(pos);
        
             ret[i++] = (tn.str.length() < (tn.tok.length() + MIN))
        
                 ? null              // CASE-1: TagNode.str is too short to even have the attribute
                 : tn.AV(attribute); // CASE-2: Possibly has it: Save the result of TagNode.AV(...)
         }
        
         return ret;
        
      • update

        🡅  🡇    
        public static int[] update​(java.util.Vector<? super TagNode> html,
                                   int sPos,
                                   int ePos,
                                   Attributes.Filter f)
        Modifies the contents of each instance of a 'TC.OpeningTags' element found in the input Vector. The type of update that's performed is defined by the parameter Filter 'f'. Each time a TagNode found in the input vectorized-html web-page, or html sub-list, is changed or modified the, original TagNode will be removed and replaced by a new, modified TagNode instance.

        NOTE: This method restricts the filtering process to the specified subrange sPos ... ePos of the HTML-Vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        f - This is a 'functional-interface' instance. It may be implemented by a lambda expression, or with an assignment to a (C Styled) function pointer. This interface is defined here in class 'Attributes'. It needs to implement a method that receives a String and a java.util.Properties, and removes all attribute key-value pairs that need to be removed from those Properties. If any changes have been made to the Properties, this must be indicated by returning TRUE as the result of this method.

        By implementing an instance of 'Filter', a programmer may selectively choose which attributes in each and every TagNode of a web-page, or sub-list, using a single lambda-expression.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed.

        These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements, as a result of this method. The key-value pairs which were requested be removed, added or changed by the Attributes.Filter parameter 'f' are noted by the contents of this array.
        Throws:
        InnerTagKeyException - The TagNode constructor that is used here when replacing TagNode instances will automatically check each attribute that is being inserted into the TagNode. If the user has added inner-tags whose names do not meet the requirements of the inner-tag naming conventions, this exception will throw.
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the attribute key-value pairs have a quotation-choice such that the chosen quotation-mark is also found within the attribute-value.

        QuotesException will also throw in the case that an attribute key-value pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        See Also:
        TagNode.allAV(boolean, boolean), TagNode.isTagNode(), TagNode.isClosing, LV
        Code:
        Exact Method Body:
         // Save Modified node-locations in a java stream (Use the "Primitive Int Stream")
         IntStream.Builder   b   = IntStream.builder();
        
         // Temp-Loop Variables
         LV          l   = new LV(sPos, ePos, html);
         Properties  p;
         TagNode     tn;
        
         for (int i=l.start; i < l.end; i++)
        
             if (
                 // Only Opening TagNode's that could possibly have attributes.
                 ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null)
        
                 // Retrieve all Attribute Key-Value Pairs.  Take note of surrounding quotes.
                 &&  ((p = tn.allAV(true, true)).size() > 0)
        
                 // Run the provided filter logic, if it returns TRUE, then build new TagNode
                 &&  f.filter(tn.tok, p)
             )
             {
                 // This makes sure not to leave out any possible "boolean" (a.k.a "Key Only") 
                 // attributes when we rebuild the new TagNode.  An example of a "boolean" attribute
                 // in HTML is "HIDDEN" which is a key that does not require any value to convey its
                 // purpose or function.  Sometimes web-page designers might type "HIDDENT=TRUE",
                 // but it is not necessary.  In any case, the "allAV(boolean, boolean)" method only
                 // returns attributes that have BOTH a 'key' AND a 'value'.
        
                 List<String> keyOnly = tn.allKeyOnlyAttributes(true).collect(Collectors.toList());
        
                 // Build a new TagNode, then replace the old one
                 tn = new TagNode(tn.tok, p, keyOnly, null, tn.str.endsWith("/>")); 
                 html.setElementAt(tn, i);
        
                 // Save the vector-index where a replacement has occurred.  The user will be
                 // provided a list of all locations where an old TagNode was replaced with a new one.
                 b.accept(i);
             }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • update

        🡅  🡇    
        public static int[] update​(java.util.Vector<? super TagNode> html,
                                   int[] posArr,
                                   Attributes.Filter f)
        Filters the contents of each instance of a 'TC.OpeningTags' element in the input Vector. The type of filter performed is defined by the parameter Filter 'f'. Each time a TagNode in the input vectorized-html web-page, or html sub-list, is changed or modified the original TagNode will be removed and replaced by a new, updated or modified TagNode instance.

        NOTE: This method restricts the removal process to only nodes specified by the 'Vector'-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        f - This is a 'functional-interface' instance. It may be implemented by a lambda expression, or with an assignment to a (C Styled) function pointer. This interface is defined here in class 'Attributes'. It needs to implement a method that receives a String and a java.util.Properties, and removes all attribute key-value pairs that need to be removed from those Properties. If any changes have been made to the Properties, this must be indicated by returning TRUE as the result of this method.

        By implementing an instance of 'Filter', a programmer may selectively choose which attributes in each and every TagNode of a web-page, or sub-list, using a single lambda-expression.

        AGAIN: This method shall only modify TagNode's if their Vector-index locations in 'html' are listed in 'posArr'.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Section Element.
         int[] posArr = TagNodeFind.all(htmlPage, TC.OpeningTags, "section");
        
         // This line uses a lambda-expression to implement a simple Attributes Filter.  This filter
         // removes any 'class' information found in the element, and then adds a 'title' attribute
         // if the TagNode does not already have a 'title' inner-tag.
         //
         // NOTE:    This filter operation will only be applied to the TagNode's that were identified
         //          by the search operation in the previous line.  Specifically, only TagNode's
         //          whose indices are in the integer-array 'posArr' will be checked against this
         //          filter lambda expression.
         //
         // ALSO:    This 'Counter' class simply 'counts' and returns successive integers, beginning
         //          at one.  It is used to 'bypass' the compiler's 'Effectively Final' rule.
         //
         // RETURNS: The returned array will contain a list of pointers to HTML SECTION Elements that
         //          were changed.  SECTION Elements that were not updated by the Attributes.Filter
         //          lambda-expression will not have a pointer in this index-array.
         
         Counter c = new Counter(1);
         
         int[] changedPosArr  = Attributes.filter(htmlPage, posArr, (String htmlTag, Properties av) ->
         {
             boolean ret = false;
        
             if (av.contains("class"))
             { ret=true; av.remove("class"); }
        
             if (! av.contains("title"))
             { ret=true; av.put("title", "Article Section Page #" + c.next()); }
        
             return ret;
         });
        
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html'. The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed.

        These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements, as a result of this method. The key-value pairs which were requested be removed, added or changed by the Attributes.Filter parameter 'f' are noted by the contents of this array.

        NOTE: It is altogether possible that the nodes listed by the parameter 'f', were not all modified! Dependent upon the behavior of the input filter, the output integer-array may be much shorter than the input-array!
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        InnerTagKeyException - The TagNode constructor that is used here when replacing TagNode instances will automatically check each attribute that is being inserted into the TagNode. If the user has added inner-tags whose names do not meet the requirements of the inner-tag naming conventions, this exception will throw.
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the attribute key-value pairs have a quotation-choice such that the chosen quotation-mark is also found within the attribute-value.

        QuotesException will also throw in the case that an attribute key-value pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        TagNode.allAV(boolean, boolean), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         for (int i: posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // If element-length < tok-length+5, there are no attributes!
             // '<', TOKEN, SPACE, ATTRIBUTE<MIN-1>, '=', '>'
             if (tn.str.length() < (tn.tok.length() + 5)) continue;
        
             // Retrieve all Attribute Key-Value Pairs.
             Properties p =  tn.allAV(true, true);
        
             // This makes sure not to leave out any possible "boolean" (a.k.a "Key Only") 
             // attributes when we rebuild the new TagNode.   An example of a "boolean" attribute
             // in HTML is "HIDDEN" which is a key that does not require any value to convey its
             // purpose or function.  Sometimes web-page designers might type "HIDDENT=TRUE", but
             // it is not necessary.  In any case, the "allAV(boolean, boolean)" method only returns
             // attributes that have BOTH a 'key' AND a 'value'.
        
             List<String> keyOnly = tn.allKeyOnlyAttributes(true).collect(Collectors.toList());
        
             // Run the provided filter logic, if it returns TRUE, then build new TagNode
             if ((p.size() > 0) && f.filter(tn.tok, p))
             {
                 // Build a new TagNode, and replace the old one.
                 tn = new TagNode(tn.tok, p, keyOnly, null, tn.str.endsWith("/>"));
                 html.setElementAt(tn, i);
        
                 // Save the vector-index where a replacement has occured.  The user will be
                 // provided a list of all locations where an old TagNode was replaced with a
                 // new one.
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • filter

        🡅  🡇    
        public static int[] filter​(java.util.Vector<? super TagNode> html,
                                   int sPos,
                                   int ePos,
                                   java.lang.String... innerTagWhiteList)
        Filters the contents of each instance of a 'TC.OpeningTags' element in the input Vector using an attribute 'white-list'. All input-Vector TagNode's that have attributes whose names are not members of the inner-tag white-list will be removed, and a new TagNode whose only attributes are members of the innerTag white-list will replace the old TagNode.

        NOTE: This method restricts the filter process to the specified subrange sPos ... ePos of the HTML Vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        innerTagWhiteList - This should be a list of attribute names that 'white-list' the attributes in each TagNode inside the vectorized-html parameter 'html'. The concept of 'white-list' means that any attribute inside any TagNode within this input Vector whose name is not in the white-list will be removed from the TagNode, and a new TagNode will be created and replace the old one in the Vector.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements. These 'replaced' TagNode's are the ones that had contained non-white-listed attribute key-value pairs.
        Throws:
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        TagNode.allAN(boolean, boolean), TagNode.isTagNode(), TagNode.removeAttributes(String[]), TagNode.isClosing, LV
        Code:
        Exact Method Body:
         TreeSet<String>         whiteList   = new TreeSet<>();
        
         // Java Streams keep a list of which TagNode's were changed
         IntStream.Builder b = IntStream.builder();
        
         // Build the tree-set with the contents of the list.  Trim them, convert to lower-case
         //
         // REMEMBER: Internally, attribute key-value pairs are returned in a java.util.Properties
         //           instance.  This Properties instance always has keys in lower case format.
        
         for (String attribute: innerTagWhiteList) whiteList.add(attribute.trim().toLowerCase());
        
         // Loop Variables, Temp Variables
         LV              l               = new LV(sPos, ePos, html);
         Vector<String>  attrToRemove    = new Vector<>();
         TagNode         tn;
        
         for (int i=l.start; i < l.end; i++)
        
             if ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null)
             {
                 // Will keep the list of attributes that didn't pass the white-list
                 attrToRemove.clear();
        
                 // List of all attributes in the TagNode, as a String-Array
                 String[] allAN = tn.allAN(true, true).toArray(String[]::new);
        
                 for (String attribute : allAN)
                     if (! whiteList.contains(attribute))
                         attrToRemove.addElement(attribute);
        
                 // if there were attributes that didn't pass...
                 if (attrToRemove.size() > 0)
                 {
                     // Build a new TagNode, and then replace the old one with the newly built one
                     // on the page or sub-page, and at the same location.
                     // NOTE: 'removeAttributes' needs a var-args String-Array, not a Vector<String>
                     tn = tn.removeAttributes(attrToRemove.toArray(StringParse.EMPTY_STR_ARRAY));
                     html.setElementAt(tn, i);
        
                     // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                     // This lists has all Vector locations where a "TagNode swap" has occurred.
                     b.accept(i);
                 }
             }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • filter

        🡅  🡇    
        public static int[] filter​(java.util.Vector<? super TagNode> html,
                                   int[] posArr,
                                   java.lang.String... innerTagWhiteList)
        Filters the contents of each instance of a 'TC.OpeningTags' element in the input Vector using an attribute 'white-list'. All input-Vector TagNode's that have attributes whose names are not members of the inner-tag white-list will be removed, and a new TagNode whose only attributes are members of the innerTag white-list will replace the old TagNode.

        NOTE: This method restricts the removal process to only nodes specified by the 'Vector'-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        innerTagWhiteList - This should be a list of attribute names that 'white-list' the attributes in each TagNode inside the vectorized-html parameter 'html'. The concept of 'white-list' means that any attribute inside any TagNode within this input Vector whose name is not in the white-list will be removed from the TagNode, and a new TagNode will be created and replace the old one in the Vector.

        AGAIN: This method shall only modify TagNode's if their Vector-index locations in 'html' are listed in 'posArr'.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Image Element.
         int[] posArr = TagNodeFind.all(htmlPage, TC.OpeningTags, "img");
        
         // This line  will "clean up" any HTML "<IMG>" elements.  If these elements are 'cluttered'
         // after the filter operation, only the 'src' and 'alt' attributes will remain.
         Attributes.filter(htmlPage, posArr, "src", "alt");
        
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements. These 'replaced' TagNode's are the ones that had contained non-white-listed attribute key-value pairs.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        TagNode.allAN(boolean, boolean), TagNode.removeAttributes(String[]), TagNode.isTagNode(), TagNode.isClosing
        Code:
        Exact Method Body:
         TreeSet<String> whiteList = new TreeSet<>();
        
         // Java Streams to keep a list of vector-indices that were updated.
         IntStream.Builder b = IntStream.builder();
        
         // Build the tree-set with the contents of the list.  Trim them, convert to lower-case
         //
         // REMEMBER: Internally, attribute key-value pairs are returned in a java.util.Properties
         //           instance.  This Properties instance always has keys in lower case format.
        
         for (String attribute: innerTagWhiteList) whiteList.add(attribute.trim().toLowerCase());
        
         for (int i: posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // If element-length = tok-length+2, THERE ARE NO ATTRIBUTES!
             if (tn.str.length() <= (tn.tok.length() + 3)) continue;
        
             // List of all attributes in the TagNode
             String[] allAN = tn.allAN(true, true).toArray(String[]::new);
        
             // List of the attributes that DIDN'T PASS the WHITE-LIST
             Vector<String> attrToRemove = new Vector<>();
        
             for (String attribute : allAN)
                 if (! whiteList.contains(attribute))
                     attrToRemove.addElement(attribute);
        
             // if there were attributes that didn't pass...
             if (attrToRemove.size() > 0)
             {
                 // Build a new TagNode, and then replace the old one with the newly built one
                 // on the page or sub-page, and at the same location.
                 // NOTE: 'removeAttributes' needs a var-args String-Array, not a Vector<String>
                 tn = tn.removeAttributes(attrToRemove.toArray(StringParse.EMPTY_STR_ARRAY));
                 html.setElementAt(tn, i);
        
                 // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                 // This lists has all Vector locations where a "TagNode swap" has occurred.
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • filter

        🡅  🡇    
        public static int[] filter​(java.util.Vector<? super TagNode> html,
                                   int sPos,
                                   int ePos,
                                   StrFilter filter)
        Filters the contents of each instance of a 'TC.OpeningTags' element in the input Vector using a StrFilter. All input-Vector TagNode's which have attributes will have the list of attribute-names tested against the provided StrFilter.test(attribute) predicate.

        If any attribute whose name fails the Predicate test, then that attribute will be removed. After testing all of a TagNode's inner-tags, if any of those attributes did fail the StrFilter.test(...) method, a new TagNode will be constructed leaving those out. Finally, the old TagNode will be removed from input HTML Vector, and replaced with the new one.

        NOTE: This method restricts the filter process to the specified subrange sPos ... ePos of the HTML Vector.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        filter - There are a plethora of available "automatically built" String filters available using the interface StrFilter's static-member methods that build StrFilter to use here. One may also write a java lambda-expression here to implement the java.util.function.Predicate.

        IMPORTANT: The StrFilter functional-interface extends Predicate<Object>. Perhaps it may seem counter-intuitive that it does not extend Predicate<String>, however, since StrFilter is a general purpose Predicate (used in numerous locations in this JAR-File 'Java-HTML' library distribution), it's a situation that allows for non-string objects (like the myriad classes which implement the interface CharSequence) to simply invoke Java's Object.toString() method to be used as input to the filter-test.

        Sadly, this means that in writing a custom-made lambda-expression for this Predicate, it is mandatory to call Java's (Object class) 'toString()' method on the input 'innerTags' - even though the input parameter 'inner-tags' is already a String.

        The rational for this inconvenience is that interface 'StrFilter' has quite a few general-purpose, statically-invoked, factory-builder routines. Reusing those methods outweighs the benefit of having these methods, here, accept a 'Predicate<String>' instead of a 'Predicate<Object>' as an input parameter. (Again, noting that StrFilter extends 'Predicate<Object>'.
        sPos - This is the (integer) Vector-index that sets a limit for the left-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'inclusive' meaning that the HTMLNode at this Vector-index will be visited by this method.

        NOTE: If this value is negative, or larger than the length of the input-Vector, an exception will be thrown.
        ePos - This is the (integer) Vector-index that sets a limit for the right-most Vector-position to inspect/search inside the input Vector-parameter. This value is considered 'exclusive' meaning that the 'HTMLNode' at this Vector-index will not be visited by this method.

        NOTE: If this value is larger than the size of input the Vector-parameter, an exception will throw.

        ALSO: Passing a negative value to this parameter, 'ePos', will cause its value to be reset to the size of the input Vector-parameter.
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements in which the key-value pairs which were requested be removed by this method, have been removed.
        Throws:
        java.lang.IndexOutOfBoundsException - This exception shall be thrown if any of the following are true:

        • If 'sPos' is negative, or if sPos is greater-than-or-equal-to the size of the Vector
        • If 'ePos' is zero, or greater than the size of the Vector
        • If the value of 'sPos' is a larger integer than 'ePos'. If 'ePos' was negative, it is first reset to Vector.size(), before this check is done.
        See Also:
        TagNode.allAN(), TagNode.isTagNode(), TagNode.isClosing, TagNode.removeAttributes(String[]), LV
        Code:
        Exact Method Body:
         // Save the list of modified TagNode's in a Java Stream
         IntStream.Builder b = IntStream.builder();
        
         // Temp Var, Loop Variable
         LV      l   = new LV(sPos, ePos, html);
         TagNode tn;
        
         for (int i=l.start; i < l.end; i++)
        
             if ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null) 
             {
                 // Build a list of all inner-tags that must be removed
                 String[] innerTagsToRemove = tn
                     .allAN(true, true)                          // Builds attibute Stream<String>
                     .filter(innerTag -> filter.test(innerTag))  // Run the user provided filter
                     .toArray(String[]::new);                    // Stream<String> -> String[]
        
                 if (innerTagsToRemove.length > 0)
                 {
                     // Build a new TagNode, and then replace the old one with the newly built one
                     // on the page or sub-page, and at the same location.
                     tn = tn.removeAttributes(innerTagsToRemove);
                     html.setElementAt(tn, i);
        
                     // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                     // The list shall contain all Vector indices where a "TagNode swap"  occurred
                     b.accept(i);
                 }
             }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();
        
      • filter

        🡅    
        public static int[] filter​(java.util.Vector<? super TagNode> html,
                                   int[] posArr,
                                   StrFilter filter)
        Filters the contents of each instance of a 'TC.OpeningTags' element in the input Vector using a StrFilter. All input-Vector TagNode's which have attributes will have the list of attribute-names tested against the provided StrFilter.test(attribute) predicate.

        If any attribute whose name fails the Predicate test, then that attribute will be removed. After testing all of a TagNode's inner-tags, if any of those attributes did fail the StrFilter.test(...) method, a new TagNode will be constructed leaving those out. Finally, the old TagNode will be removed from input HTML Vector, and replaced with the new one.

        NOTE: This method restricts the removal process to only nodes specified by the 'Vector'-index parameter 'posArr'.
        Parameters:
        html - This may be any vectorized-html web-page, or an html sub-section / partial-page. All that the variable-type wild-card '? super TagNode' means is this method can receive a Vector<TagNode> or a Vector<HTMLNode>, without throwing an exception, or producing erroneous results. Note that if a Vector<Object> is passed, and there are no instances of class TagNode contained by that Vector, then this method will simply exit gracefully.
        filter - There are a plethora of available "automatically built" String filters available using the interface StrFilter's static-member methods that build StrFilter to use here. One may also write a java lambda-expression here to implement the java.util.function.Predicate.

        IMPORTANT: The StrFilter functional-interface extends Predicate<Object>. Perhaps it may seem counter-intuitive that it does not extend Predicate<String>, however, since StrFilter is a general purpose Predicate (used in numerous locations in this JAR-File 'Java-HTML' library distribution), it's a situation that allows for non-string objects (like the myriad classes which implement the interface CharSequence) to simply invoke Java's Object.toString() method to be used as input to the filter-test.

        Sadly, this means that in writing a custom-made lambda-expression for this Predicate, it is mandatory to call Java's (Object class) 'toString()' method on the input 'innerTags' - even though the input parameter 'inner-tags' is already a String.

        The rational for this inconvenience is that interface 'StrFilter' has quite a few general-purpose, statically-invoked, factory-builder routines. Reusing those methods outweighs the benefit of having these methods, here, accept a 'Predicate<String>' instead of a 'Predicate<Object>' as an input parameter. (Again, noting that StrFilter extends 'Predicate<Object>'.

        AGAIN: This method shall only modify TagNode's if their Vector-index locations in 'html' are listed in 'posArr'.
        posArr - This integer-array is expected to receive a "Pointer-Integer Array." These are usually generated by the NodeSearch 'Find' classes, and are simply lists of index-pointers into a Vectorized HTML Web-Page Vector. The int[] array passed to this parameter will specify the TagNode's in the Vector whose attributes will be partially removed via a call to TagNode.removeAV(...) and replaced.

        For Example:
         // This line will retrieve an array "index-pointer" to every HTML Image Element.
         int[] posArr = TagNodeFind.all(htmlPage, TC.OpeningTags, "img");
         
         // Build an instance of StrFilter
         //
         // NOTE: The 'true' parameter indicates that the attribute name should be considered
         //       and compared using a CASE INSENSITIVE fashion.
         
         StrFilter f = StrFilter.strListKEEP(true, "src")
        
         // This line  will "clean up" any HTML "<IMG>" elements.  If these elements are 'cluttered'
         // after the filter operation, only the 'src' attribute will remain.
         Attributes.filter(htmlPage, posArr, f);
        
        Returns:
        An integer-array whose elements function as 'Vector'-index pointers into the original vectorized-html web-page parameter 'html.' The nodes/references pointed to by the pointers in this array are the nodes/elements that were changed. These indicated TagNode's (the ones pointed to by the elements of this return-array) are the ones that have been replaced by new TagNode elements in which the key-value pairs which were requested be removed by this method, have been removed.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - If any of the elements in 'posArr' contain index-pointers that are out of range of Vector-parameter 'page', then java will, naturally, throw this exception.
        TagNodeExpectedException - This exception shall throw if an identified Vector-index must point-to an instance of TagNode, but that index instead holds some other HTMLNode instance (either CommentNode or TextNode). If an integer-position array (int[] posArr) is passed, but that array has an index pointing-to - something besides a TagNode - then this exception will be thrown.
        OpeningTagNodeExpectedException - When a Vector position-index holds an instance of TagNode, but that TagNode is one in which its boolean 'isClosing' field set to TRUE, then this exception shall throw. When passing an int[] posArr (integer-array) of Vector-indices, there is code which expects that each of those locations pointed-to to contain "Opening HTML Element Tags", then this exception's throw will inform the user.
        See Also:
        TagNode.allAN(), TagNode.isTagNode(), TagNode.isClosing, TagNode.removeAttributes(String[])
        Code:
        Exact Method Body:
         // Use Java Stream to keep a list of Vector-Locations that were updated / modified.
         IntStream.Builder b = IntStream.builder();
        
         for (int i: posArr)
         {
             HTMLNode n = (HTMLNode) html.elementAt(i);
        
             if (! n.isTagNode()) throw new TagNodeExpectedException(i);
        
             TagNode tn = (TagNode) n;
        
             if (tn.isClosing) throw new OpeningTagNodeExpectedException(i);
        
             // Minimum TagNode.str Length (in order to have attributes): '<', TOKEN, SPACE '>'
             if (tn.str.length() < (tn.tok.length() + 3)) continue;
        
             // Build a list of all inner-tags that must be removed
             String[] innerTagsToRemove = tn
                 .allAN(true, true)                          // Builds attibute Stream<String>
                 .filter(innerTag -> filter.test(innerTag))  // Run the user provided filter
                 .toArray(String[]::new);                    // Stream<String> -> String[]
        
             if (innerTagsToRemove.length > 0)
             {
                 // Build a new TagNode, and then replace the old one with the newly built one
                 // on the page or sub-page, and at the same location.
                 tn = tn.removeAttributes(innerTagsToRemove);
                 html.setElementAt(tn, i);
        
                 // Java's IntStream-Builder is just a way to "build" a short list of integer's.
                 // The list shall contain all Vector indices where a "TagNode swap"  occurred
                 b.accept(i);
             }
         }
        
         // Build the IntStream, Convert the IntStream -> int[], Return it.
         return b.build().toArray();