[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] XPath 2.0 Best Practice Issue: Graceful Degradation
Hi Folks, I submit for your consideration the following XPath 2.0 Best Practice issue. Please see the questions at the bottom. [Definition] Graceful degradation is the ability to continue working, albeit with reduced functionality, when some expected capability is absent. ISSUE How do we design XPath 2.0 statements to degrade gracefully? EXAMPLE Consider this snippet of an XML instance document: <airplane tailnum="C3H1"> <altitude unit="feet">20000</altitude> </airplane> An airplane, with tail number C3H1, is flying at an altitude of 20,000 feet. PROBLEM Design an XPath statement that specifies this behavior: convert the altitude value (20000) from feet to meters. Design the XPath in a way that it specifies a behavior that will degrade gracefully. SOLUTION, VERSION #1 Here is one solution to the problem: //airplane[@tailnum='C3H1']/altitude * .3048 The behavior specified by this XPath statement is: navigate to the altitude element, atomize its value, and multiply it by .3048 PROBLEM WITH VERSION #1 The XPath statement assumes there exists an airplane element with tailnum C3H1, and that the airplane has a child element named altitude. No alternative behavior is specified for the situation in which the expected elements are absent. The XPath statement does not degrade gracefully. (More precisely, the behavior specified by the XPath statement does not degrade gracefully) SOLUTION, VERSION #2 This XPath statement checks that the expected elements are present: if (exists(//airplane[@tailnum='C3H1']/altitude)) then //airplane[@tailnum='C3H1']/altitude * .3048 else (: behavior to occur when the expected elements are absent :) The XPath statement specifies a behavior for both the situation where the expected elements are present, as well as where they are absent. The XPath statement degrades gracefully ... well, it degrades a bit gracefully. PROBLEM WITH VERSION #2 The XPath statement assumes the contents of the altitude element is a number. No alternative behavior is specified for the situation where the expected numeric value is absent. The XPath statement does not degrade as gracefully as we would like. SOLUTION, VERSION #3 This XPath statement checks that the altitude has a numeric value: if (exists(//airplane[@tailnum='C3H1']/altitude)) then if (//airplane[@tailnum='C3H1']/altitude castable as xs:double) then //airplane[@tailnum='C3H1']/altitude * .3048 else (: behavior to occur when the expected numeric value is absent :) else (: behavior to occur when the expected elements are absent :) The XPath statement specifies a behavior for the cases where the expected elements are present, where they are absent, where the altitude value is numeric, and where the altitude value is not numeric. The XPath statement degrades more gracefully than the prior versions ... but it still can be improved. PROBLEM WITH VERSION #3 The XPath statement assumes the value of the altitude element is in feet. No alternative behavior is specified for the situation where the expected feet value is absent. The XPath statement does not degrade as gracefully as we desire. SOLUTION, VERSION #4 This XPath statement checks that the altitude value is in feet: if (exists(//airplane[@tailnum='C3H1']/altitude)) then if (//airplane[@tailnum='C3H1']/altitude castable as xs:double) then if (exists(//airplane[@tailnum='C3H1']/altitude/@unit)) then if (//airplane[@tailnum='C3H1']/altitude/@unit = 'feet') then //airplane[@tailnum='C3H1']/altitude * .3048 else if (//airplane[@tailnum='C3H1']/altitude/@units = 'meters') then //airplane[@tailnum='C3H1']/altitude else (: behavior to occur when the expected feet value is absent :) else (: behavior to occur when the expected unit attribute is absent :) else (: behavior to occur when the expected numeric value is absent :) else (: behavior to occur when the expected elements are absent :) The XPath statement specifies a behavior for the cases where the expected elements are present, where they are absent, where the altitude value is numeric, where the altitude value is not numeric, where the unit attribute is present, where the unit attribute is absent, where the value of the unit attribute is feet, where the value of the unit attribute is meters, and where the value of the unit attribute is neither feet or meters. At last, we have an XPath statement that degrades gracefully. QUESTIONS 1. Graceful degradation is all about specifying behavior when an "expected capability" is absent. In the above example, the "expected capability" is information: elements, attributes, data, and datatypes. What other types of things might be absent which should be accounted for? 2. In the above examples I didn't specify the alternate behavior, I simply wrote a comment. Is it possible to be more specific without knowledge of the context in which the XPath statement is used? 3. In version #3 I tested the altitude value to see if it has a numeric value by using the "castable as" operator: if (//airplane[@tailnum='C3H1']/altitude castable as xs:double) then Should I have instead used the "instance of" operator: if (//airplane[@tailnum='C3H1']/altitude instance of xs:double) then What do you recommend? 4. I can't think of any other improvements to the XPath statement to make it degrade more gracefully. Can you suggest further improvements? /Roger
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] |
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|