Extending Find and Replace for Microsoft Office FrontPage 2003
Microsoft® Office FrontPage® 2003
Summary: Learn the basics of creating queries that find and replace text in Microsoft Office FrontPage 2003 documents, the XML Query schema that FrontPage uses to save and reuse queries, and the Microsoft Visual Basic for Applications (VBA) objects that you can use to create your own powerful solutions to extend FrontPage. (13 printed pages)
Understanding the Query Schema
Developing Custom Find and Replace Solutions
With the new find and replace capabilities in Microsoft® Office FrontPage® 2003, you can easily develop powerful find and replace solutions. Initially, the find and replace capabilities in FrontPage are similar to the find and replace capabilities in other Microsoft Office 2003 applications. However, unlike other Office applications, FrontPage uses Extensible Markup Language (XML) to perform queries. You can create queries with FrontPage by using the Find and Replace dialog box, or you can create them manually by using the simple Query schema described in this article.
Once you have created a query, you can then save it to a file, which allows you to easily reuse it or share it with others. You can also use the query strings contained in the query files to develop custom find and replace solutions by using the new SearchInfo object that is included in the FrontPage 2003 Visual Basic® for Applications (VBA) object model.
You can use the Find and Replace dialog box in FrontPage to create queries. The Find and Replace dialog box provides a useful way to create queries. In the lower-right corner of the dialog box, there are two Query icons. The folder icon allows you to open saved queries, and the disk icon allows you to save queries.
To demonstrate how this works, you can use the following steps to create and save a simple query by using the Find and Replace dialog box. These steps create a query that uses the default settings.
- On the Edit menu, click Replace.
- Type "frist" in the Find what text box.
- Type "first" in the Replace with text box.
- Click the Save query button.
- Type "NewQuery" in the Filename text box.
- Click Save.
When you save a query, FrontPage automatically saves it with an .fpq file extension. By default, new queries are saved to the FrontPage Queries folder for the current user located at C:\Documents and Settings\<user>\Application Data\Microsoft\FrontPage\Queries. However, you can save them to any folder you want.
After following the preceding steps, you will find a saved query called NewQuery.fpq in the default folder. If you open the file in Notepad, you will see a very simple statement in the XML to find the text "frist" and replace it with the text "first".
<?xml version="1.0" encoding="utf-8" ?> <fpquery version="1.0"> <queryparams /> <find text="frist" /> <replace text="first" /> </fpquery>
The additional options in the Find and Replace dialog box allow you to create more complex queries. You can even create conditional queries. For example, you might want to change all occurrences of the B element to a U element but only when they occur inside of a TABLE element. This query would resemble the following XML query string.
<?xml version="1.0" encoding="utf-8" ?> <fpquery version="1.0"> <queryparams /> <find tag="b"> <rule type="insideTag" tag="table" /> </find> <replace type="changeTag" tag="u" /> </fpquery>
Working with Regular Expressions
In addition to creating queries that find specific text and elements, you can create queries that use regular expressions. Regular expressions allow you to create patterns of characters that describe one or more strings to find when searching text or code. These are especially useful when you don't know the exact text or code that you are looking for or when you are looking for all occurrences of text or code with one or more similarities. For more information on the different regular expressions that you can use within a FrontPage find and replace, see Regular Expressions.
Understanding the Query Schema
As shown above, all the queries that you create use a custom XML schema. This relatively simple XML schema contains only five elements but provides a considerable amount of flexibility and power for creating queries that give you greater control over find and replace capabilities within FrontPage. The syntax for these elements is shown below.
<?xml version="1.0" encoding="utf-8" ?> <fpquery> <queryparams /> <find> <rule /> </find> <replace /> </fpquery>
The first line of the query syntax indicates the document type declaration. The version attribute indicates that the document conforms to version 1.0 of the XML specification. The encoding attribute indicates that the XML document is encoded using the UTF-8 character set. This line is necessary for FrontPage to be able to parse the XML query string.
Note XML stands for Extensible Markup Language. Similar to HTML, XML is a markup language designed for the Internet. However, unlike HTML, which was designed to define formatting of Web pages, XML was designed to describe data. You can use XML to develop custom schemas. As with HTML, the World Wide Web Consortium defined the specifications for XML. For more information on XML and the XML specification, see Extensible Markup Language on the World Wide Web Consortium Web site.
Query Schema Elements
The FrontPage Query schema elements are defined in detail in the following sections.
The fpquery element is the top-level container element for FrontPage queries. This element is required and contains one required attribute.
<fpquery> <queryparams /> <find /> <replace /> </fpquery>
Table 1. Attributes of the fpquery element
|version||string||Required. Specifies the schema version that is being used. For FrontPage 2003, the expected value is "1.0".|
The queryparams element defines special find functions that you want FrontPage to take into consideration when executing a query. This element is optional. If omitted, all attributes default to FALSE.
Table 2. Attributes of the queryparams element
|matchcase||boolean||Optional. Matches the find and replace text to the exact case as specified in the find and replace strings.|
|wholeword||boolean||Optional. Matches the whole word as specified in the find string and will not locate occurrences where the text is nested within other words.|
|ignorewhitespace||boolean||Optional. Matches words that are next to each other but may appear on separate lines either in code or in the page as it is displayed in the browser. If the regexp attribute equals TRUE, FrontPage ignores the ignorewhitespace attribute because a regular expression can define whether to find strings with spaces.|
|regexp||boolean||Optional. Performs a find by using a regular expression.|
|inhtml||boolean||Optional. Searches for the find string in the HTML source code.|
|diacritics||boolean||Optional. Matches a find string that contains diacritic characters in Hebrew and Arabic text.|
|kashida||boolean||Optional. Matches a find string that contains Kashida characters.|
|alefhamza||boolean||Optional. Matches a find string that contains Alefhamza characters.|
|hangul||boolean||Optional. Matches a find string that contains Hangul characters.|
The find element specifies either the text or the name of the element for which to search. This element is required and contains two optional attributes; however, all find elements must contain one of the optional attributes. Additionally, this element may have one or more rule elements that specify HTML rules to apply when searching.
<find> <rule /> </find>
Table 3. Attributes of the find element
|text||string||Optional. Specifies a find string that contains the text for which to search.|
|tag||string||Optional. Specifies a find string that contains the name of the element for which to search.|
The replace element specifies either the replacement text or the replacement action to perform on an element. This element is optional and contains six optional attributes.
Table 4. Attributes of the replace element
|text||string||Optional. Specifies the text with which to replace the found text.|
|action||string||Optional. Specifies the action to take when replacing HTML elements. Can be one of the following string values:
|html||string||Optional. Specifies the HTML string with which to replace found text.|
|tag||string||Optional. Specifies the element name with which to replace a found tag.|
|attribute||string||Optional. Specifies the attribute for which to replace a value.|
|value||string||Optional. Specifies the replacement value for an attribute.|
The rule element specifies HTML rules that define how FrontPage should perform a find and replace operation. This element is optional and contains one required and seven optional attributes. The rule element is a child element for the find element and may be a sibling of or a parent to another rule element.
<rule ...> <rule ... /> </rule>
The attributes of a rule element change depending on the value of the type attribute.
Table 5. Attributes of the rule element
|type||string||Required. Specifies how to apply the rule to the find string.
|attribute||string||Optional. When the type attribute equals "attribute", specifies the name of the attribute. For example,
|compare||string||Optional. When the type attribute equals "attribute", specifies a comparison operator that indicates a comparison value for the attribute. For example,
|value||string||Optional. When the type attribute equals "attribute", specifies a value for an attribute comparison. For example,
|negate||boolean||Optional. Switches the meaning of the type attribute to its opposite when the type attribute equals "containsText", "containsTag", or "insideTag". For example, when the type attribute is set to "insideTag", setting the negate attribute to "true" changes the rule to mean "Not Inside Tag". If omitted, the negate attribute defaults to "false". For example,
|text||string||Optional. When the type attribute equals "containsText", specifies the text. For example,
|tag||string||Optional. When the type attribute equals "containsTag", specifies the name of the element. Examples,
Developing Custom Find and Replace Solutions
Add-ins are a common way to extend the functionality of Office applications. To this end, FrontPage provides the VBA object model. By using this object model, you can create powerful custom solutions that extend the find and replace functionality in FrontPage beyond what is contained in the application. For more information about how to work with the VBA object model and how to create add-ins, see Getting Started for FrontPage developers on MSDN.
In the FrontPage 2003 object model, you will find a new SearchInfo object as well two methods and several new properties that you can use to develop your own custom solutions to extend the find and replace capabilities. The following table identifies the methods and objects that you would use to create a custom find and replace solution.
Table 6. Methods and objects for find and replace
|SearchInfo object||Provides programmatic access to find and replace capabilities in FrontPage. Use the SearchInfo object to define search queries, text, rules, and options.|
|CreateSearchInfo method||A member of the Application object, you would use the CreateSearchInfo method to create an empty SearchInfo object.|
|Find method||A member of the FPHTMLDocument object, you would use the Find method to develop more complex find and replace solutions that specify XML query strings by using the QueryContents property.|
|Action property||A member of the SearchInfo object, the Action property sets or returns an fpSearchAction constant that defines the type of search that you want to perform. The value of the Action property can be one of the following fpSearchAction constants.
|Find property||A member of the SearchInfo object, the Find property sets or returns a String that represents the text or the name of the element for which to search.|
|Options property||A member of the SearchInfo object, the Options property returns an FpSearchOptions constant that represents the parameters of a search. The Options property can be one or more of the following FpSearchOptions constants.
|QueryContents property||A member of the SearchInfo object, the QueryContents property sets or returns a String that is an XML representation of the query. This String must adhere to the Query schema.|
|ReplaceWith property||A member of the SearchInfo object, the ReplaceWith property sets or returns a String that represents the text to replace the text specified in the Find property.|
Programming Find and Replace Operations
Using the above objects, methods, and properties, you can write very simple code that performs a textual find and replace. For example the following code takes the find and replace operation introduced at the beginning of this article and uses code to find all occurrences of "frist" and replace them with "first".
Sub SimpleFindAndReplace() Dim objSearch As SearchInfo Set objSearch = Application.CreateSearchInfo objSearch.Action = fpSearchReplaceAllText objSearch.Find = "frist" objSearch.ReplaceWith = "first" ActiveDocument.Find objSearch End Sub
Note that the above code uses the CreateSearchInfo method to create an empty SearchInfo object. Then by using this empty object, the code specifies the action (to replace all text), the text ("frist"), and the replacement text ("first"). It then uses the Find method for the FPHTMLDocument object to execute a search by using the SearchInfo object.
Alternatively, you could use the QueryContents property of the CreateSearchInfo method along with the XML query string that you created earlier to create a comparable find and replace solution. For example, the following example does exactly the same thing as the previous example.
Sub QueryStringFindAndReplaceAll() Dim objSearch As SearchInfo Set objSearch = Application.CreateSearchInfo objSearch.QueryContents = "<?xml version=""1.0"" " & _ "encoding=""utf-8"" ?>" & _ "<fpquery version=""1.0"">" & _ "<queryparams />" & _ "<find text=""frist"" />" & _ "<replace text=""first"" />" & _ "</fpquery>" objSearch.Action = fpSearchReplaceAllText ActiveDocument.Find objSearch End Sub
Note that the second example required several more lines. In this case, you set the QueryContents property to the query string that you created earlier in this article. You could also write this same code as show in the following example.
Sub QueryStringFindAndReplace() Dim objSearch As SearchInfo Dim objDocument As IHTMLTxtRange Dim objFound As IHTMLTxtRange Dim blnFound As Boolean Set objDocument = ActiveDocument.body.createTextRange Set objFound = ActiveDocument.body.createTextRange Set objSearch = Application.CreateSearchInfo objSearch.QueryContents = "<?xml version=""1.0"" " & _ "encoding=""utf-8"" ?>" & _ "<fpquery version=""1.0"">" & _ "<queryparams />" & _ "<find text=""frist"" />" & _ "<replace text=""first"" />" & _ "</fpquery>" objSearch.Action = fpSearchReplaceText Do blnFound = ActiveDocument.Find(objSearch, objDocument, objFound) Loop While blnFound = True End Sub
The preceding example also sets the QueryContents property to the same query string. However, in this case, the code also uses the IHTMLTxtRange object. When you set the Action property to fpSearchReplaceText, you can use the Find method's two optional parameters to step through each change occurrence-by-occurrence. These two parameters require IHTMLTxtRange objects, so the code declares two different IHTMLTxtRange objects, which are then used in the Find method. The syntax for the Find method is as follows:
Find(info, limits, startRange)
The info parameter of the Find method specifies the SearchInfo object that contains the search text, rules, and options. Note that the second example above uses the QueryContents property to define a find and replace query, while the first example uses the Action, Find, and ReplaceWith properties of the SearchInfo object. This allows the SearchInfo object to identify the test to find and to specify the text with which to replace it.
The limits parameter specifies the IHTMLTxtRange object that represents the portion of the page against which to perform a find and replace. To search the entire document, you can use the createTextRange method of the FPHTMLBody object, as shown in the example above. This sets the limits of the range to search to the entire body of a page. However, you could also perform a find and replace against a selection by using the createRange method of the IHTMLSelectionObject object. This sets the limits for the range to search to only the text that is selected in the FrontPage window. The code to do this would look like the following example.
Set objDocument = ActiveDocument.Selection.createRange
The startRange parameter provides a reference to the found text. When the return value for the Find method is True, you can use the startRange parameter to select the found text. This is especially important if you want to step through a find and replace operation, stopping at each found word. In this case, you would set the Action property of the SearchInfo object equal to fpSearchReplaceText because the fpSearchReplaceText constant enables you to perform a find and replace that stops at each occurrence of found text.
Therefore, in the preceding example, if you wanted to select each occurrence as it is found, you could use the Select method of the IHTMLTxtRange object to select the returned text within the Do loop, as shown in the following sample.
Do blnFound = ActiveDocument.Find(objSearch, objDocument, objFound) objFound.Select Loop While blnFound = True
Note The SearchInfo object allows you to perform textual find and replace only. You cannot perform replace operations that modify HTML. To do this, you can use the DocumentHTML property to perform a global search and replace of all occurrences of a string. The DocumentHTML property returns a string that represents both the HTML and the text for a Web page.
Programming with Regular Expressions
Using a query, you can easily perform find and replace operations that use regular expressions. To demonstrate this, the following example uses the SearchInfo object to execute a find based on a query string that uses a regular expression. The regular expression it specified is " t:a*n ". This regular expression will locate all words that start with a "t" and end with an "n". For example, it will locate tan, ten, ton, tin, and teen as well as Tennessean. The asterisk indicates that any number of letters can occur between the "t" and the "n". For more information see, Regular Expressions.
Sub QueryContents() Dim objSearch As SearchInfo Dim objRange As IHTMLTxtRange Dim objLimits As IHTMLTxtRange Dim strQuery As String Dim blnFoundMatch As Boolean strQuery = "<fpquery version=""1.0"">" & _ "<queryparams regexp=""true"" />" & _ "<find text=""t:a*n"" />" & _ "</fpquery>" Set objRange = ActiveDocument.body.createTextRange Set objLimits = ActiveDocument.body.createTextRange Set objSearch = Application.CreateSearchInfo objSearch.Action = fpSearchFindText objSearch.QueryContents = strQuery Do blnFoundMatch = ActiveDocument.Find(objSearch, objLimits, objRange) Loop While blnFoundMatch = True End Sub
As you have seen in this article, the new find and replace functionality in FrontPage 2003 provides powerful search capabilities not only within the Find and Replace dialog box but also from using the VBA object model. You can also perform searches for patterns of words by using regular expressions. These capabilities give you greater control over searches and give you the ability to share search queries and develop complex custom solutions.