Title: XPath for Cost Based Estimating
1XPath for Cost Based Estimating
2Introduction
- XPath, as implemented by ePace, provides the user
with a tool to define a value for an operation
that is custom to their shop. Typically the XPath
expression is used to provide a quantity that is
used as the basis for a table lookup or is
multiplied by a flat rate to provide either time
or material usage.
3Abstract
- XPath is an expression language that allows the
processing of values conforming to the data model
defined in XQuery/XPath Data Model (XDM). The
data model provides a tree representation of XML
data sources as well as atomic values such as
integers, strings, and booleans, and sequences
that may contain both references to nodes in an
XML data source and atomic values. The result of
an XPath expression may be a selection of nodes
from the input data sources, or an atomic value,
or more generally, any sequence allowed by the
data model. The name of the language derives from
its most distinctive feature, the path
expression, which provides a means of hierarchic
addressing of the nodes in an XML tree.
4Session Contents
- 1. Determine what the calculation needs to do.
- 2. Determine field names.
- 3. Determine the data type of the result field.
- 4. Determine how you will cost your operation
based on the data type. - 5. Find your fields relative to the current
object. - 6. Write your expression in simple terms.
- 7. Write your expression in XPath.
- 8. Test your expression.
- 9. Enter your expression into ePace.
- 10. Use your expression.
- 11. Syntax.
- 12. Examples.
51. Determine what the calculation needs to do.
- The first step is to determine what the formula
needs to accomplish. - Determine which fields hold reference values and
what conditions need to be met first. - Then determine the formula to arrive at the
desired results.
61. Determine what the calculation needs to do.
- The first step is to determine what the formula
needs to accomplish. Determine which fields hold
reference values and what conditions need to be
met first. Then determine the formula to arrive
at the desired results. - Example
- To preflight a file, allow 15 minutes to review
the job jacket, create a job directory on the
storage server, transfer the file into the
director and open the file in preflight software.
Then allow 6 seconds per page to check the
preflight, 10 pages per minute, 600 per hour. - Formula .25 (number of pages / 600). Result
is in decimal hours.
72. Determine field names.
- There are two way to determine the names of the
fields to use.
82. Determine field names.
- There are two way to determine the names of the
fields to use. - One is to go to Administration -gt System
Configuration -gt Object Model -gt Object Model
Browser, select the target object, click on the
Fields tab and find the fields you need. - This will also show any Calculated Fields that
may not appear on a screen but will make your
statement easier.
92. Determine field names.
102. Determine field names.
112. Determine field names.
- The other way is to open an estimate and go to
details. - Go to Administration -gt Toggle Debug Mode.
- This will show you the names of the fields in the
Object Model (dataset). - Drill into an operation like the one you will be
describing, in our example a Prepress Operation. - In the label area of the field of interest there
will be a name. Hover over the field to show the
information. It will appear as - EstimatePrepressOp, expr ../_at_quantityOrdered
122. Determine field names.
132. Determine field names.
142. Determine field names.
- Example
- For the preflight example, the fields we need are
EstimateQuantity/_at_quantityOrdered,
EstimateQuantity/_at_numPages, EstimatePart/_at_numSigs.
- In the Object Model Browser we find that the
calculated field totalPages is _at_numPages
_at_numSigs so that is what we will use.
153. Determine the data type of the result field.
- Go to the Object Model Browser, select the target
object, click on the Fields tab and find the Type
of the field for your result.
163. Determine the data type of the result field.
- Example
- EstimatePrepressOp object quantity field has a
Type of Integer
174. Determine how you will cost your operation
based on the data type.
- If the field is an integer, as quantity normally
is, then you need to decide how to define your
cost. - In a Prepress Operation size you define hours per
unit. Since XPath will return integer units, to
get decimal time, times should be entered as 0.01
hour per unit.
184. Determine how you will cost your operation
based on the data type.
- Example
- Preflight operation size 99 x 99 Qty Up To
99,999,999 Hours 0.01. XPath will return an
integer value for units of hundredths of an hour.
195. Find your fields relative to the current
object.
205. Find your fields relative to the current object
- All field references in XPath are relative to the
object of the result field.
215. Find your fields relative to the current
object.
- Version 17 Cost Based Estimating Objects
- Company
-
- Estimate
-
- EstimatePart
-
- EstimateQuantity
-
- --------------- ----------------
------------------ ------------------
-------------- -------------- - EstimatePrepressOp - EstimatePress -
EstimateFinishingOp - EstimateOutsidePurch -
EstimatePaper - EstimateInk - EstimateActivity -
225. Find your fields relative to the current
object.
- We refer to these relationships as
- ??EstimatePart is a child of Estimate
- Estimate
-
- EstimatePart
- ??Estimate is the parent of EstimatePart
- ??EstimatePress is a sibling of EstimatePaper
- EstimatePress - EstimatePaper
-
235. Find your fields relative to the current
object.
- The notation for these is
- ../ moves up a generation
- ../ltobject namegt moves to a sibling
- ltobject namegtcondition/ltobjectgt
- moves down a generation.
245. Find your fields relative to the current
object.
- Examples
- If starting location is EstimatePrepressOp,
parent is EstimateQuantity which is referred to
as ../
255. Find your fields relative to the current
object.
- Examples
- If starting location is EstimatePrepressOp,
sizeDenominator (a field in company) is
../../../../_at_sizeDenominator - The series of ../ refer, in sequence, to
EstimateQuantity, then EstimatePart, then
Estimate, then Company
265. Find your fields relative to the current
object.
- Examples
- The condition is a way to select a field of a
certain value and find data for that record.
../EstimatePress_at_pressIndicator0/_at_runSizeWidth
refers to the sibling object EstimatePress with a
specific record where pressIndicator 0 (primary
press) and gets the runSizeWidth.
275. Find your fields relative to the current
object.
- Examples
- To use this runSizeWidth, because we store sizes
as integers, you need to divide the value by the
system's size denominator so the expression would
be - (../EstimatePress_at_pressIndicator0/_at_runSizeWidth
div ../../../../_at_sizeDenominator )? - 38 would be stored as 608 if your
sizeDenominator is 16.
285. Find your fields relative to the current
object.
- Examples
- To get a value from an object outside of the tree
shown above you use a notation like this
(../EstimatePress_at_pressIndicator0/press/ - _at_gripperAllowance
- This would go to the sibling object,
EstimatePress and select the primary press
record, find the press on that record and return
the gripper size.
295. Find your fields relative to the current
object.
- Examples
- To get a value from an object outside of the tree
by using a direct pointer, use syntax like this
/InventoryItem_at_id'123Test'/_at_unitPrice - If the object is a singleton (single record
object like many setup objects), then the record
selection is not necessary - /EstimateSetup/_at_paperRoundingMode
306. Write your expression in simple terms.
- Formula from Step 1 .25 (number of pages /
600)? - (¼ hour ( sum(numPages for all parts) / 600))
100 - Remember, units are integers so to get 1/100 of
an hour we must multiply by 100 to get units of
.01 hours. 67 units times .01 hours .67 hours
317. Write your expression in XPath.
- (.25 (sum(../../../EstimatePart/_at_totalPages)
div 600)) 100 - Note
- To sum a value you must go to the parent and then
sum the children. Here we go up to the Estimate
and then refer to the EstimateParts. This will
give us the total number of pages in all parts of
the Estimate.
328. Test your expression.
- Go to a sample estimate and manually calculate
the result you want the system to return. - In our example, we have a large perfect bound
book of 1,566 pages. - 1566 _at_ 600/hour 2.61 hours .25 2.86
- 2.86 hours 100 286 units
338. Test your expression.
- Go to a sample estimate and get the object number
as a data starting point. - Example
- Go to your estimate detail Prepress tab and hover
over a prepress operation drilldown icon. At the
bottom of the browser window will appear a URL
like http//epace.samplecompany.com/estimating/ob
ject/EstimatePrepressOp/detail/5987
348. Test your expression.
358. Test your expression.
- Go to Administration -gt System Tools -gt XPath
Evaluator. - In Object Type enter the result's object.
- The primary key is the number at the end of the
URL. - The data type is from step 3.
- The Expression is the one you have written.
- Hit the Evaluate button and the Result should
produce the value you expect.
368. Test your expression.
379. Enter your expression into ePace.
- Go to Administration -gt System Setup -gt
Estimating -gt Misc Setup -gt Estimate Expression
Setup. - Add New Record.
- Enter a name, calculation type and copy your
expression into the appropriate area, Expression
Prepress or Expression Finishing.
389. Enter your expression into ePace.
3910. Use your expression.
- Go to either a Prepress Workflow or a Finishing
Operation. - In the Quantity Calc Method select XPath
Expression - Choose your new expression in the Estimate
Expression field
4010. Use your expression.
4111. Syntax
- ePace uses XPath 1.1 with custom extensions. If
you get an XPath book, it may have version 2.0
expressions which will not be understood by
ePace.
4211. Syntax
- Any time an expression uses more than one
operator, it is necessary to know what precedence
is used. For XPath, this is (highest to lowest) - ( ) 'grouping'
- 'filter'
- 'unary minus'
- div mod 'multiplication division modulus'
- - 'addition subtraction'
- ! lt lt gt gt 'relational (comparison)'
- 'union'
- not 'negation'
- and 'conjunction'
- or 'disjunction'
- Operators at the same precedence level are always
evaluated left-to-right. Parentheses can be used
to force the expression to evaluate in a
different order than the default.
4311. Syntax
- Here are the some of the syntax statements that
are currently available - Comparison operators
- 'equal to'
- ! 'not equal to'
- gt 'greater than'
- gt 'greater than or equal to'
- lt 'less than'
- lt 'less than or equal to'
- Contains 'list of values contains test value'
- not 'reverses the true/false value of its
argument'
4411. Syntax
- Here are the some of the syntax statements that
are currently available - Conditional Statement
- iif(ltvaluegt condition ltvaluegt, ltresultgt, ltelse
resultgt) - this may be nested
4511. Syntax
- Here are the some of the syntax statements that
are currently available - Arithmetic Statements
- 'plus'
- - 'minus'
- 'multiply by'
- div 'divide by'
- mod 'modulus'
- null-to-zero 'if _at_addHours returns null,
- null-to-zero(_at_addHours) returns 0'
4611. Syntax
- Here are the some of the syntax statements that
are currently available - Summary Statements
- sum(ltvalue listgt)?
- floor(ltvaluegt) result is rounded down toward
negative infinity (negative numbers increase in
absolute value)? - ceiling(ltvaluegt) result is rounded up toward
positive infinity - round(ltvaluegt) result is rounded. lt .5 rounds
down - gt .5 rounds up
- count(ltvaluegt) result is number of records
4711. Syntax
- Here are the some of the syntax statements that
are currently available - String
- number(ltstring valuegt) 'result is a number. Use
to convert string values before math' - contains(string_1, string_2) 'returns true if
string_1 contains string_2' - concat(ltstring_1gt, ltstring_2gt, ltstring_3gt)
- 'concatenates strings'
- starts-with(ltstring_1gt,ltstring_2gt) 'returns true
if string_1 starts with string_2, case
sensitive' - string(ltvaluegt) 'returns value as string, used
to return a number as a string' -
4811. Syntax
- Here are the some of the syntax statements that
are currently available - String
- string-length(ltstringgt) 'returns number of
characters in the string' - substring(ltstringgt,offset,length) 'returns a
substring of ltlengthgt characters starting at
ltoffsetgt ' - substring-after(ltstring_1gt,ltstring_2gt) 'returns
the part of string_1 that follows the 1st
occurance of string_2 ' - substring-before(ltstring_1gt,ltstring_2gt) 'like
substring-after but returns the part before' - current-date() 'returns the current date and can
be used as a comparison in a iif statement' - current-user() 'returns the current user'
4911. Syntax
- Here are the some of the syntax statements that
are currently available - Notes
- There is no min or max function that will
compare different fields so use this format - To return minimum value of x or y use iif (x lt
y,x,y)? - The min and max functions in XPath only return
the minimum or maximum value within a field. - There is no case statement so use nested iif
statements. - There is no variable declaration.
- All statements must be included in a single
statement. You cannot return multiple values. - The first expression that returns a true in a
nested iif statement returns the value and ends
the iif. - It is like writing if xy then x end if, if
yz then z end if
5012. Examples
- For a simple price list
- 1-10 _at_ 1.75
- 11-25 _at_ 1.50
- 26 and over _at_ 1.25
- ((iif (../_at_quantityOrdered lt 10,
(../_at_quantityOrdered 1.75, - iif (../_at_quantityOrdered gt 11 and
../_at_quantityOrdered lt 25, (../_at_quantityOrdered
1.50, (../_at_quantityOrdered 1.25))))?
5112. Examples
- Final Size in 8.5 x 11 equivalents
- ((../../_at_finalSizeHeight div (../../../../_at_sizeDen
ominator)) - (../../_at_finalSizeWidth div (../../../../_at_sizeDen
ominator))? - 93.5)?
5212. Examples
- Banner Hemming - result is final size
- perimeter feet
- (((../../_at_finalSizeHeight div
- (../../../../_at_sizeDenominator 12))
(../../_at_finalSizeWidth div - (../../../../_at_sizeDenominator 12))) 2
../_at_quantityOrdered
5312. Examples
- Grommets - for each part, put a grommet along
each side. Max span 4 feet, minimum 4 per piece
(each corner)? - ../_at_quantityOrdered (ceiling((../../_at_finalSizeHe
ight div (../../../../_at_sizeDenominator 12)) div
4 ) 2 - ceiling((../../_at_finalSizeWidth div
(../../../../_at_sizeDenominator 12)) div 4 ) 2)?
5412. Examples
- Laminating - 28" wide - run inches. If the sheet
width is over 28" it has to run short edge into
the laminator, if under 28" then long edge. - (iif((../EstimatePress_at_pressIndicator0/_at_runSize
Width div (../../../../_at_sizeDenominator)gt28, - ((../EstimatePress_at_pressIndicator0/_at_runSizeWidt
h div (../../../../_at_sizeDenominator)), - ((../EstimatePress_at_pressIndicator0/_at_runSizeHeig
ht div (../../../../_at_sizeDenominator))? - )) ../_at_sheetsOffPress
5512. Examples
- Laminating - 28" wide - run inches - add 20 if
under 7 point or over 16 point or quantity is
under 1000. If the sheet width is over 28" it has
to run short edge into the laminator, if under
28" then long edge. - iif(../EstimatePaper1/paperWeight/_at_caliper lt
.007,1.2, - iif(../EstimatePaper1/paperWeight/_at_caliper gt
.016,1.2, - iif(../_at_sheetsOffPress lt 1000,1.2,1)))
- (iif((../EstimatePress_at_pressIndicator0/_at_runSize
Width div (../../../../_at_sizeDenominator)gt28, - ((../EstimatePress_at_pressIndicator0/_at_runSizeWidt
h div (../../../../_at_sizeDenominator)), - ((../EstimatePress_at_pressIndicator0/_at_runSizeHeig
ht div (../../../../_at_sizeDenominator))? - )) ../_at_sheetsOffPress
5612. Examples
- Laminate material per side in MSI
- (../EstimatePress_at_pressIndicator0/_at_runSizeWidth
div ../../../../_at_sizeDenominator) - (../EstimatePress_at_pressIndicator0/_at_runSizeHeigh
t div ../../../../_at_sizeDenominator)? - ../_at_sheetsOffPress div 1000
5712. Examples
- To apply a calculation to the first part of an
estimate - iif(../../_at_id min(../../../EstimatePart/_at_id),ltva
lue or expressiongt,0)? - For the Preflight Operation this would be
- iif(../../_at_id min(../../../EstimatePart/_at_id),
- (.25 (sum(../../../EstimatePart/_at_totalPages)
div 600)) 100,0)?
5812. Examples
- To get the total material cost for an Estimate
Part, from a prepressOp or finishingOp for
Canadian tax - This shows 2 conditions, EstimateActivity.estimate
Quantity (../_at_id) AND EstimateActivity.hours
0 - Return 12 of the total material cost on the part
- 0.12 sum(../EstimateActivity_at_estimateQuantity(
../_at_id) and null-to-zero(_at_hours) 0/_at_cost)?
59