Parsing Rules Technical Details |
Top Previous Next |
Parsing rules are pretty simple at the basic level of "if you find this then put the text here". This section covers the technical stuff -- for some actual examples that are easy to understand, see the next section with the Parsing Set Example.
Types of Rules (Actions)
If you're getting data from a web form that you design or have designed for you, then it should be easy to set up the rules because you would naturally design the form to ask for all of the information in a format that's very similar to the Campground Master data. In that case, most or all of your rules will be the basic "Extract Field Value" type and will be very simple to implement.
Other types of rules are available to handle special situations that would mostly be an issue if you're trying to parse a request from some other service that uses different types of data. For instance, they might have a field that has the dollar charge for extra adults but does not give the actual number of adults, like Campground Master needs it. You could use the rules to convert various charge amounts into the appropriate number of adults.
Each action type, or rule type, is detailed below. Each type of rule accepts different parameters (before, after, compare-to or set-value text), depending on its function. All of them also need a field descriptor and allow other options like append and convert options, except the Ignore Field rule. Note that the number of characters can be specified also, but to keep it simple this option is covered separately below.
Extract Field value
This is the basic rule used to extract text from the data and set a field value to that text. All you need to do is enter the text that will appear before the value (before-text) and the text that will appear after the value (after-text). For instance, if the request has the customer's last name after the label "LASTNAME:", then enter that label for the before-text. You also need to tell it where to stop extracting the value, so for instance if you know there won't be anything else on that line, enter "\r" (carriage return) for the after-text.
You can leave the before-text blank if you want to start extracting immediately from where the position pointer is in the data -- this assumes that the Where to Look is set to "After Previous Field".
Extract Field value if not equal to 'Compare to'
This rule is similar to the previous one in that it looks for the field between the before and after text, but it also lets you specify an exception to extracting the data. In addition to the before and after text, fill in the Compare-to text. The data found will be extracted only if it does not match that text. For instance, the request might specify a site number, or "N/A" if they don't select a site. Use this rule to extract the site number specified as long as it's not "N/A".
You might wonder why there's not a rule to extract a field value if it is equal to the compare-to text. That's because the "Set Field value if Compare to matches" rule below can do the same thing.
This rule can also be used to extract a field value only if the text is non-blank, by leaving the Compare-to text blank. In other words, rather than just extracting a blank field, it would skip the extraction and not set the field at all.
Set Field to a fixed value (always)
This rule doesn't actually extract anything from the text. It simply sets a field value no matter what (assuming this parsing set is used). You just enter the set-value-to text for the field.
This rule is generally used to set a default value, for instance to set the How-found field to a specific value for all online requests, or perhaps to set a default for the number of adults in case they didn't specify it in the request. Remember that a rule could follow later in the set that extracts the field if it does find the value in the request, which would replace the default value.
Set Field value if 'Text before field' is found
This rule is similar to the previous one, except it looks for some before-text and only sets the value you specify if that text is found (ignoring anything else actually in the request). This would be used for things like special options that appear as unique words in the request. For instance if the request would have something like "2 ADULTS" in it for the number of adults, it's hard to extract a value appearing before the text. So you can add a number of rules, one for each reasonable number, such that each rule would set the # Adults field to the specific value it finds (e.g. if it finds "3 ADULTS", set the # Adults field to "3").
Set Field value if non-blank data is found
This rule looks for before and after text like the normal Extract rule -- but instead of setting the field value to the extracted text, it will set the field to a specified value as long as the text between the before and after text is not blank. (Remember that whitespace characters like space, tab, carriage return and line feed are considered blank.
Set Field value if 'Compare to' matches
This rule looks for before and after text like the normal Extract rule -- but instead of setting the field value to the extracted text, it will set the field to a specified value as long as the text between the before and after text matches the compare-to text. As an example, lets say the request is expected to have either "Electric: 50A" or "Electric: 30A". If you have a preference field for 50A (which must be set to "Must Have" to show that they want 50A), then you could use this rule. Set the before-text to "Electric:", the after-text to "A", the Compare-to text to "50", and the Set-value-to text to "Must Have".
Set Field value if 'Compare to' doesn't match
This is similar to the previous rule, except that the field will be set if the data does not match the compare-to value.
Set Field value if no previous value was set (default)
This rule is intended as a catch-all case, for instance if you have several Set Field value rules for the same field, checking for various conditions, and then need to set the field to a particular value if none of the other checks produced a value. This is essentially defining a default value.
Note that the "previous value" it's looking for is according to the Field Descriptor, not just the same before and after text in previous rules. So if you have several rules looking for an "Electricity" value but the rules actually set different data fields (e.g. 50A, 30A, and 20A preference fields), then this doesn't act as a default for "Electricity" -- it would only act as a default for one specific data field.
There is a subtle difference between using this at the end of the other comparisons and just setting the field to a fixed value as a default before the comparison rules (whereas the default field value would be overwritten if one of the comparison rules were satisfied). The key is that this particular rule does nothing unless the before and after text is located, so the field will not get set at all if the request does not have the before & after text.
Ignore Field (set position for next field)
This rule only has one parameter, the before-text, which is just the text that you're looking for to activate this rule. This rule doesn't set any fields, it just looks for the specified before-text, and if it's found then the position pointer for following rules is set to that position (on the next character after the before-text found).
Obviously this rule only has a use if there is a rule following it that has "After previous field" for where to look. It can be useful for setting a starting point, for instance if a number of fields are in a known order without unique labels in front of each one. Just locate some identifying text that comes before all of the values -- for instance the request may have a label "Address:", which is known to be followed by several lines with the pieces of the address. Use the Ignore Field rule to find "Address:", and then a number of Extract Field rules with blank before-text to read in the data fields sequentially.
Number of Characters vs. Text after field
Any rule that has "Text after field" as a parameter will also have "Number of characters" as an option. Either or both of these values can be specified, depending on what you need to do.
If the after-text is specified but the number of characters is blank (or zero), then it will simply extract all of the text between the before and after text as described in the actions above.
If the after-text is blank but the number of characters is 1 or more, then it will extract exactly that number of characters (starting after the before-text), and leave the position pointer at the next character. This is useful for parsing data values of a fixed length, especially from a string of data with no labels or field dividers. Remember that you can also leave the before-text blank, so it starts exactly where the last rule left off. Note that if it reaches the end of the request before the required number of characters are found, it will just keep what it finds -- this can be used to just extract everything to the end of the request, for instance if there are notes of unknown length at the end, with multiple lines and no unique ending character to stop with.
If both the after-text and the number of characters is specified, then the number of characters is assumed to be a maximum. So it must find the after-text, and the position pointer will be moved to the next character after that as usual, but if the data extracted between the before and after text is longer than this maximum number of characters then it will be truncated. For instance, this can be useful to extract just a fixed part of a line but leave the position pointer starting on the next line.
General Parsing Rule Order
There are a couple restrictions for the order of parsing rules in a parsing set. Regardless of the order that the fields appear in the request text, the order of parsing rules must follow these guidelines for successful parsing:
•Reservation fields and Customer fields can be in either order and intermixed if needed. However there must be at least one Reservation field and one Customer field successfully parsed before a Transaction field can be parsed (due to the required linking relationship).
•If you're extracting more than one Transaction, using indexed records like Trans[1], Trans[2], etc., don't intermingle index values and keep them in order -- e.g. all rules for the first transaction must appear before any for the second transaction. See below for more information.
Indexed Records in Field Descriptors
As just mentioned above, it's possible to extract data for multiple transactions for a single reservation request. This is handy for adding memos or other items to the transactions for the reservation. This is generally used only for transactions.
To create a parsing rule to do this, you must modify the field descriptor manually, e.g. after using Browse to select the field on the Edit Parsing Rule dialog. Insert an index number inside square brackets, just before the colon of the field descriptor -- for example: "Trans[0]:Tran_Amount". The index value can start at 0, and go as high as needed. If no index value is specified, [0] is assumed.
The index values must be in order in the parsing rule list, e.g. all fields for Tran[1] must appear before Tran[2] fields, [2] before [3], etc. However you can skip index numbers if you like (to leave room for inserting others later, for instance). It's also OK if data isn't extracted for all transactions, resulting in missed index numbers. For instance if it extracts fields for Trans[1] and then doesn't find any rules (or valid data to extract) for Trans[2], it can still extract data for Trans[3]. Only the two transactions found will be used. The numbers are just a way to create separate records and indicate which fields go with which record, but the numbers themselves are not important.
When you view the Online Request Details, the indexes shown for extracted data will appear a little differently -- they will have a "+" number in front, like "Transactions[+1]". These numbers may not match the index values you use in the rules -- they will increment without gaps in the numbering.
Using "After Previous Field" for Where to Look
Aside from the general order of fields mentioned above, the order of the rules don't matter if the "Where to look" for all of your rules are "Anywhere in the text" because it will start at the beginning of the request data each time. But if you use the "After previous field" option, then naturally the rules need to be in the same order that the fields to be extracted will appear in the request data. Therefore it's recommended to use the "Anywhere" option unless there's a specific requirement for getting fields in a certain order without looking for unique text to indicate the field position.
To be more specific -- as the engine goes through the rules, it keeps track of the last position it looked at (e.g. where it found the last field's data). If you select "After previous field", it starts looking from that position to satisfy this rule (e.g. to find the "before text" for the next rule). If a rule uses "Anywhere in text", the engine starts over at the beginning for that rule.
Note that sometimes every character is important for locating data. Lets say the following text has 3 values that you need to extract, where the first number is # adults, the second is # children, and the 3rd is # pets:
Extras: 1,2,3 (end of line)
You can do this with 3 parsing rules, each with Extract Value for the Action:
•The first rule would be a "Look Anywhere" rule, with "Extras:" for the before-text and "," for the after-text. It would extract the value "1" which appears between the specified text (the leading space is removed). After getting that value, the text position pointer is now on the "2" (it's positioned on the character following the after-text specified in the previous rule).
•The 2nd rule would be a "Look after previous field" rule, with blank before-text (so it starts extracting immediately starting with the "2"), and after-text ",". So it will extract the value "2", and the pointer is left on the "3".
•Finally the 3rd rule would be another "Look after previous field" rule, with blank before-text and after-text "\r" (to stop at the end of the line) so it extracts the "3".
There is also a special way to position the pointer for future rules without extracting the text. This is the "Ignore Field" rule action. Specify the before-text and it will locate that text, leaving the position pointer on the next character (after the before-text it found). This could be useful in the example above if you wanted to skip the first value, for instance. The first rule would have an action of "Ignore Field", then you would insert another "Ignore Field" rule with "," as the before-text. This would move the position pointer to the 2nd value ("2"), setting the stage for the next rule to extract the 2nd value.
Special Characters and Text Considerations
When entering a rule, there are certain limitations for what you can use in the before-text, after-text, compare-to and set-value-to fields (and there are some workarounds for these limitations).
•You can't enter the space character at the beginning or end of the entry fields (because leading and trailing spaces are stripped out of the dialog entry fields automatically). However if you need to have the parser actually use a space, for instance to enter a space character in the "Set value to" field that's not surrounded by other characters, you can use the hexadecimal escape sequence "\x20".
•You can use the \t and \r escape sequences in the before-text and after-text values to look for "tab" and "carriage return" characters respectively. For instance it's common to have "\r" for the "Text after field" setting, to tell it that the data stops at the end of the line.
•Sometimes text data includes both carriage return and line feed characters at the end of lines. All line-feed characters in the request text are removed before parsing, to make it more consistent and avoid confusion between the two characters. Therefore lines will always end in a carriage return character (\r). Also note that there may be more than one \r at the end of lines, so don't assume only one will be there when setting up parsing rules.
•When text is extracted (e.g. from between the before-text and after-text), any carriage return or tab characters are converted to spaces (because Campground Master data fields cannot contain control characters). In addition, leading and trailing spaces are removed from the parsed text before doing any comparisons -- keep this in mind when setting a "Compare to" value -- the extracted text being compared would never contain the carriage return (\r) or tab (\t) characters, and it could not start or end with a space.
•Before-text and After-text values are case sensitive and must be entered exactly as they will appear in the request text.
•For the Compare-to actions, the comparison is not case-sensitive (e.g. the compare-to text "tent" will match "TENT" in the request).
•Text in Set-value-to is naturally case sensitive (the data field will be set to exactly that text -- after any spaces are trimmed from the ends of course).
Requirements for a Valid Reservation Request
Regardless of the actual rule definitions used, a Parsing Set is "complete" as long as it contains rules that result in the following fields being extracted from a given request:
Reservation : First Night
Reservation : Last Night
Customer : Last Name
That's the minimum amount of information needed for a reservation to be created, so your parsing rules need to at least get this information from the request text. Ideally you want to get as much information out of the request as possible, though, as long as the format is reliable enough to avoid getting false information.
Note that the pseudo-field "Departure Date" or "Number of Nights" can also be used to get the Last Night value.
In addition, an Online Request ID must be present, either found by default or extracted using a parsing rule. The logic is as follows:
•For E-mail requests, it looks for the "Message-ID" header and will use that for the request ID by default.
•You can also set up a parsing rule to set the online request ID, which will override any extracted from the Message-ID. You may want to do this to get a specific ID from the request itself for later reference, or you may need to do it if you have to paste text to process that doesn't have the E-mail header information.
•If no request ID is found or parsed, an error will be shown. The request cannot be saved as a real reservation without an ID, but if you view the request you can enter a request ID manually (just be sure to use something unique that would never match an ID from another request.)
Default Field Values
Reservations - Several reservation fields will be set to default values if they're not parsed out of the data:
Confirmation # - uses the formatting rules specified in online setup
Status - set to "Pending" unless the Guarantee Info field is filled in, then it will be "Guaranteed"
Reservation Type - set to the default specified in Program Options
Date Made - set to the current date
Time Made - set to the current time
Operator Made - set to the current operator, or the default specified in the online setup
Transactions - If the request includes any transaction information (for instance a deposit amount), then you can also create one or more transactions for the reservation. The only value you actually need to create or extract is either the Each amount or the Total for the transaction. The rest of the fields will default as follows, if they're not explicitly set by the rules:
Transaction Type - set to "Deposit"
Transaction Category - set to the same as Transaction Type (e.g. "Deposit")
Quantity - left empty
Each - set to the same as the Total amount, or Total / Quantity if there's a quantity
Total - set to the same as the Each amount, or Each x Quantity if there's a quantity
Receipt # - set using the normal formatting for receipt #'s
Description - set to the default specified in the online setup
Payment Method - set to the default specified in the online setup
Operator - set to the current operator, or the default specified in the online setup
Date, Time and Shift - set to the current date, time and shift
Note: If you have parsing rules for transaction fields but the resulting Total is zero after parsing (unless it's a Memo transaction type), then the transaction will not be added to the reservation. For Memo transactions, the Description field must be non-blank for it to add the transaction.
Duplicated Fields
When making a reservation manually, some values you enter are automatically copied to matching fields in both the Reservation and Customer records. However this does not happen for online reservation parsing, so the following fields need to have duplicated rules for the associated Reservation and Customer fields if you want the data to be set in both places:
# Adults
# Children
# Pets
Extra Vehicles
Extra Trailers
Exception -- the Guarantee Info field is copied from the Reservation to the Customer automatically.
Also note that the Discount Used reservation field is normally copied into the next available customer Discounts field (#1, 2, or 3) when entering manual reservations. Since this complication isn't possible when parsing, just extract the reservation's Discount Used field. The next time you enter Transactions, the discount will be carried over automatically to the customer as appropriate.
In general it's OK to parse the same text multiple times, or even set a data field value multiple times. If a field is parsed out that already had a value, the new value will replace the old one unless the "Append" option is specified.
Date Formats
When parsing date fields, the date must be in a recognizable format. There are a few different formats that are recognized, shown below.
Mon dd, yyyy - e.g. Mar 25, 2007 -- Month must be 3-letter English abbreviation
mm/dd/yyyy - (or d/m/y for non-U.S.) e.g. 3/25/07, 03/25/2007
Mon/dd/yyyy - e.g. Mar/3/2007
yyyy/mm/dd - e.g. 2007/03/25
yyyy/Mon/dd - e.g. 2007/Mar/25, Month must be 3-letter English abbreviation
Note that a dash or period (- or .) can be used instead of a slash ( / ), and that the day or month numbers can be with or without leading zeroes (e.g. 3 or 03). Except for the formats where the year is first, the year can be either 4 digits or 2 digits. Where the 3-letter month abbreviation is used, it can be upper or lower case, or mixed.
Pseudo-Fields
There are several "fake" fields that can be used to help get the data parsed into useful values. These pseudo-fields appear in the list of fields in the Select a Data Field dialog (at the top, above the normal fields). These special fields are described below, noting any special handling that can be done.
In general you can use a parsing rule to extract text from the request into a pseudo-field instead of a real data field, to handle special formats that the request might use. The engine will do further processing on that text to set the real Campground Master data fields appropriately.
"Append" option note -- In all but a few cases, the Append option in a parsing rule is ignored for pseudo-fields because of the special processing these fields already do. The special cases are the pseudo-fields for credit card number, date, and name. These allow appending because there are so many possible formats the credit card information might be sent.
Customer Pseudo-fields:
•First and Last Name -- Use when the whole name is in one string, like "John Smith". Assumes the last word is the Last Name, and the rest is First Name(s).
•Last, First Name -- Use when the name is in one string with the last name first. If a comma is not found, the first word is assumed to be the Last Name and the rest is First Name(s).
•City, State, Zip -- Use when the string is the whole bottom address line with all three of these. It will put them into the separate data fields.
Reservation Pseudo-fields:
•Departure Date (Last + 1) -- Use when the departure or check-out date is present instead of the Last Night.
•Number of Nights -- Use when there is no last night or departure date present, just the number of nights. Note that a rule to extract the First Night must appear prior to this one.
•Number of sites requested -- If the request could be for more than one site, set this field so it knows how many linked reservations must be created.
•Unit ID from E-mail requests -- Use for E-mail requests if the request contains a special ID, not the same as a site number (see Online Setup -- Site Data Fields).
•Unit Type from E-mail requests -- Use for E-mail requests if the request contains a unit type, not the same as a site type (see Online Setup -- Site Data Fields).
•Unit ID from Reservation Friend -- Use for Reservation Friend requests for the site name sent in their reservation data (see Online Setup -- Site Data Fields).
•Credit Card # (Guarantee) -- To extract the credit card number for the guarantee information (these are pseudo-fields because the credit card info is stored in the Guarantee Info fields in a special format, not as separate fields).
•Credit Card Name (Guarantee) -- For the credit card name.
•Credit Card Exp Date (Guarantee) -- For the credit card expiration date as one string. Will accept several formats, like 0705, 7/05, 07/05, 7/31/05, or 7/31/2005.
•Credit Card Exp Month (Guarantee) -- For just the month part of the expiration date, if it's a separate field.
•Credit Card Exp Year (Guarantee) -- For just the expiration year as a separate field.
•Credit Card CVV (Guarantee) -- For the CVV/CVC2 code on the credit card.
Transaction Pseudo-fields:
•Credit Card # -- (same as for reservation fields above).
•Credit Card Name -- (same as for reservation fields above).
•Credit Card Exp Date -- (same as for reservation fields above).
•Credit Card Exp Month -- (same as for reservation fields above).
•Credit Card Exp Year -- (same as for reservation fields above).
•Credit Card CVV -- (same as for reservation fields above).