CallXML 3.0 Development GuideHome  |  Frameset Home

  XPath Expressions: Part 1  |  TOC  |  XPath Functions  

Advanced XPath Addressing

In the effort to further illustrate the various Xpath expressions that a developer can employ to pull XML data from a document, we present yet another example to study. While the above sample details basic Xpath expressions, it doesn't really delve into how we can filter results based on element or attribute values using predicates, nor does it illustrate the differences between a relative and absolute Xpath expression. Below, we will cover these topics, and others that you will doubtlessly find useful when developing your CallXML applications.


Xpath Predicate Expressions

You may not know it, but you have already used a predicate expression in the above example. At it's most basic, a predicate is an embedded statement within the Xpath expression that filters our results based on node position, or element/attribute value(s). A predicate expression is pretty easy to spot; such expressions are always enclosed within a set of [square brackets] that define the node position, or the value that our filtering will be based on. Our very first Xpath statement in the above example shows how we use a predicate expression to select the first instance of the 'disc' node:

<assign var="child" expr="list(//disc[1]/child::*/text())"/>

In our next example, we will throw more throw a few more predicate expressions in the mix to show how we can grab specific groups of element/attribute values, and how we can filter our results based on the values themselves.

Xpath Expression Operators

Like any well-designed markup, Xpath comes with a built-in set of operators that we can use to further tweak our returned results. Those of us who have worked with basic ECMAScript will doubtlessly find these familiar:


Be aware that any angle-bracket operators (>, <), will need to be quoted via the standard XML rules to avoid a parse error:


While it's a bit out of scope for this humble document to show off every possible permutation of XPath operators, our next example does hows a few of these in action to help show how these can be implemented in your own applications.


AdvancedExpressions.xml


<?xml version="1.0" encoding="UTF-8"?>

<callxml version="3.0">

<!-- fetch our XML document, and assign it to a locally scoped CallXML variable -->
<fetch value="AdvancedAddress.xml" var="myFetch" type="xml"/>

  <block label="Addressing" value="$myFetch;">



    <log>*** select the first 'addy' element that is a child of the 'addresses' element:</log>
    <assign var="address1" expr="/var/myFetch/addresses/addy[1]/text()"/>
    <log>*** ADDRESS 1: $address1; ***</log> 
    <wait value="1s"/>
 
    <assign var="address2" expr="/var/myFetch/addresses/addy[last()]/text()"/>
    <log>*** select the last 'addy' element that is a child of 'addresses':</log>
    <log>*** ADDRESS 2: $address2; ***</log> 
    <wait value="1s"/>

    <assign var="address3" expr="/var/myFetch/addresses/addy[last()-1]/text()"/>
    <log>*** select the next to last 'addy' element that is a child of 'addresses':</log>
    <log>*** ADDRESS 3: $address3; ***</log> 
    <wait value="1s"/>


    <assign var="address4" expr="list(/var/myFetch//addresses/addy[position()&lt;4]/text())"/>
    <log>*** select the first three 'addy' elements that are children of 'addresses':</log>
    <!-- note that we need to call the 'list' function to output this array of values -->
    <log>*** ADDRESS 4: $address4; ***</log> 
    <wait value="1s"/>

    <assign var="address5" expr="list(//addy[@state]/text())"/>
    <log>*** select all 'addy' elements that have a 'state' attribute defined:</log>
    <!-- again, we need to call the 'list' function to output the array of values -->
    <log>*** ADDRESS 5: $address5; ***</log> 
    <wait value="1s"/>

    <assign var="address6" expr="list(//addy[@state='California']/text())"/>
    <log>*** select all 'addy' elements that have an attribute named 'state', and have a value of 'California':</log>
    <log>*** ADDRESS 6: $address6; ***</log> 
    <wait value="1s"/>

    <assign var="address7" expr="list(//addy[@val&gt;22.3]/text())"/>
    <log>*** select all 'addy' elements that have a 'val' attribute whose value is greater than '22.3':</log>
    <log>*** ADDRESS 7: $address7; ***</log> 
    <wait value="1s"/>


    <assign var="address10" expr="list(//*)"/>
    <log>*** select all elements in the document:</log>
    <log>*** ADDRESS 10: $address10; ***</log> 
    <wait value="1s"/>


    <assign var="address11" expr="list(//addy[@*]/text())"/>
    <log>*** select all 'addy' elements that have an attribute of any kind:</log>
    <log>*** ADDRESS 11: $address11; ***</log> 
    <wait value="1s"/>

    <assign var="address12" expr="list(//addy[@state='California']/text() | //addy[@state='Florida']/text())"/>
    <log>*** all 'addy' elements that have attributes named 'state' and have a values of 'California' AND attributes that have values of 'Florida'</log>
    <!-- illustrates using the '|' (AND) operator to select two paths:  -->
    <log>*** ADDRESS 12: $address12; ***</log> 
    <wait value="1s"/>
 
  </block>

</callxml>


AdvancedAddress.xml


<?xml version="1.0" encoding="UTF-8"?>

<mynodes>

  <addresses>
  <addy state="Florida" val="11.1"> 111 pine street </addy>
  <addy state="Georgia" val="22.2"> 222 saint andrews boulevard </addy>
  <addy state="California" val="33.3"> 333 twin lakes drive </addy>
  <addy val="44.4"> 444 masters boulevard </addy>
  <addy state="New York" val="55.5"> 555 bimini lane <crime level="high">higher</crime> </addy>
  <addy state="Montana" val="55.5"> 666 goodrich lane </addy>
  <addy> 777 happyjack street</addy> 
  </addresses>

</mynodes>




Download It!

If you'd rather just download the Xpath example files rather than typing them out yourself, then you must be government-employed. In any case, we aim to please, so you can grab the source files for the above code below, and upload it to your hosting server, (or ours), to give it a test run on the CallXML3.0 platform.



  CallXML 3.0 source code




  ANNOTATIONS: EXISTING POSTS
moshe
5/25/2007 11:56 AM (EDT)
I'm confused as to how the "fetch" attribute "var" becomes associated with the particular XML nodes I'm trying to read.

In this example, I see the fully-qualified path name of "/var/myFetch/addresses" to find the addresses node inside the myFetch var.

I also see "//addr" as a path to the nodes; presumably this works because of the block statement's attribute of "value" being set to myFetch.

So are these two alternative formulations equivalent?



moshe
5/25/2007 11:58 AM (EDT)
How to use assign:

To use xpath with assign, the following three attributes must be given:

var -- name of the variable
value - the variable that contains the xpath read in via fetch
expr - the xpath expression


login
  XPath Expressions: Part 1  |  TOC  |  XPath Functions  

© 2008 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site