com.edustructures.sifworks.tools.xpath
Class SIFXPathContext

java.lang.Object
  extended by org.apache.commons.jxpath.JXPathContext
      extended by org.apache.commons.jxpath.ri.JXPathContextReferenceImpl
          extended by com.edustructures.sifworks.tools.xpath.SIFXPathContext

public class SIFXPathContext
extends org.apache.commons.jxpath.ri.JXPathContextReferenceImpl

SIFXPathContext provides APIs for the traversal of SIF Data Objects (SDO) using the XPath syntax.

SIFXPath Interprets XPath Syntax on SIF Data Objects

SIFXPath is based on JXPath and uses an intuitive interpretation of the XPath syntax in the traversal of SIF Data Objects. Here are some examples:

Example 1: Simple Property Access

SIFXPath can be used to access simple properties of SIF Data Objects.
  StudentPersonal student = new StudentPersonal();
  student.setRefId( ADK.makeGUID() );
  student.setName( new Name( NameType.LEGAL, "Johnson", "Tim" ) );
 
  SIFXPathContext context = SIFXPathContext.newSIFContext( student );
  // Print out the RefId of the Student
  System.out.println( "RefId: " + context.getValue( "@RefId" ) );
            
  // Print out the Last Name of the Student
  System.out.println( "Last Name: " + context.getValue( "Name/LastName" ) );
 

Example 2: Iterating an array using XPath

SIFXPath can be used to iterate over arrays within SIF Data Objects.
 <blockquote>
  StudentPersonal student = new StudentPersonal();
  PhoneNumberList pnl = new PhoneNumberList();
  pnl.add( new PhoneNumber( PhoneNumberType.ANSWERING_SERVICE, "555-555-2224" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.PRIMARY, "555-555-6521" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.FAX, "555-555-8745" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.MEDIA_CONFERENCE, "555-555-3215" ) );
  student.setPhoneNumberList( pnl );
 
  SIFXPathContext context = SIFXPathContext.newSIFContext( student );
  // Print out the phone numbers of the student
  Iterator phones = context.iterate("PhoneNumberList/PhoneNumber");
  System.out.println( "Phone Numbers...." );
  while( phones.hasNext() ) {
        PhoneNumber phone = (PhoneNumber)phones.next();
        System.out.println( "Type: " + phone.getType() + " Number: " + phone.getNumber() );
  }
 

Example 3: Using advanced iterating

SIFXPath can be used to find elements that match specific criteria. In this example, all elements that have a text value are returned
 <blockquote>
  StudentPersonal student = new StudentPersonal();
  student.setRefId( ADK.makeGUID() );
  student.setName( new Name( NameType.LEGAL, "Johnson", "Tim" ) );
  PhoneNumberList pnl = new PhoneNumberList();
  pnl.add( new PhoneNumber( PhoneNumberType.ANSWERING_SERVICE, "555-555-2224" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.PRIMARY, "555-555-6521" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.FAX, "555-555-8745" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.MEDIA_CONFERENCE, "555-555-3215" ) );
  student.setPhoneNumberList( pnl );
  SIFXPathContext context = SIFXPathContext.newSIFContext( student );
  // Print out all elements that have a text value
  Iterator textNodes = context.iterate("//*/text()");"
  "System.out.println( "Text Values...." );
  while( textNodes.hasNext() ) {
        Element value = (Element)textNodes.next();
        System.out.println( "Tag: " + value.getElementDef().tag( SIFVersion.SIF20) + " = " + value.getTextValue() );
  }
 

Example 4: Using XPath Functions

Most standard XPath functions can be used to return and find values. Examples of useful functions are the 'concat' and 'substring' functions, which can be used both as arguments to predicates or to format the resulting value. Here are some examples of advanced XPath
 <blockquote>
  ADK.initialize();
  StudentPersonal student = new StudentPersonal();
  student.setRefId( ADK.makeGUID() );
  student.setName( new Name( NameType.LEGAL, "Johnson", "Tim" ) );
  PhoneNumberList pnl = new PhoneNumberList();
  pnl.add( new PhoneNumber( PhoneNumberType.ANSWERING_SERVICE, "555-555-2224" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.PRIMARY, "555-555-6521" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.FAX, "555-555-8745" ) );
  pnl.add( new PhoneNumber( PhoneNumberType.MEDIA_CONFERENCE, "555-555-3215" ) );
  student.setPhoneNumberList( pnl );
 
  SIFXPathContext context = SIFXPathContext.newSIFContext( student );
  // Print out all attributes in this object
  Iterator allAttributes = context.iterate("//@*");
  System.out.println( "All Attributes...." );
  while( allAttributes.hasNext() ) {
        SimpleField nextAttr =(SimpleField) allAttributes.next();
        System.out.println(  "Attribute:  @" + nextAttr.getElementDef().tag( SIFVersion.SIF20) + " = " + nextAttr.getTextValue() );
  }
 
  // Print out all Elements in this object
  Iterator allNodes = context.iterate("//*");
  System.out.println( "All Elements...." );
  while( allNodes.hasNext() ) {
        Element nextNode =(Element) allNodes.next();
        System.out.println(  "Node: " + nextNode.getElementDef().tag( SIFVersion.SIF20) + " = " + nextNode.getTextValue() );
  }
 
   //Use the concat function
  String concat = (String)context.getValue( "concat(//LastName, ', ',//FirstName,  ' - ', //PhoneNumber[@Type='0096']/Number)" );
  System.out.println("Result of Concat operation: " + concat );
 
   // use the substring fuction
  String substring = (String)context.getValue( "substring(//PhoneNumber[@Type='0096']/Number, 5)" );
  System.out.println( "PhoneNumber Substring = " + substring );
 

Built In Function reference

SIFXPath has a number of built-in functions that can be used. In addition, additional functions can be defined.

Here is a list of some of the built-in functions

Function
Description
fn:substring(string,start,len)
fn:substring(string,start)
Returns the substring from the start position to the specified length.

Index of the first character is 1. If length is omitted it returns the substring from the start position to the end

Example: substring('SIFWorks',1,4)
Result: 'SIFW'

Example: substring('SIFWorks',2)
Result: 'FWorks'

concat(string,string,...) Returns the concatenation of the strings

Example: concat('Hello ',' - ','World')
Result: 'Hello - World'

starts-with(string1,string2) Returns true if string1 starts with string2, otherwise it returns false

Example: starts-with('XML','X')
Result: true

substring-before(string1,string2) Returns the start of string1 before string2 occurs in it

Example: substring-before('12/10','/')
Result: '12'

substring-after(string1,string2) Returns the remainder of string1 after string2 occurs in it

Example: substring-after('12/10','/')
Result: '10'

translate(string1,string2,string3) Converts string1 by replacing the characters in string2 with the characters in string3

Example: translate('12:30','30','45')
Result: '12:45'

Example: translate('12:30','03','54')
Result: '12:45'

Example: translate('12:30','0123','abcd')
Result: 'bc:da'

normalize-space(string)
normalize-space()
Removes leading and trailing spaces from the specified string, and replaces all internal sequences of white space with one and returns the result.
If there is no string argument it does the same on the current node

Example: normalize-space(' The    SIFWorks  ADK ')
Result: 'The SIFWorks ADK'

contains(string1,string2) Returns true if string1 contains string2, otherwise it returns false

Example: contains('XML','XM')
Result: true

Using functions from the ADKFunctions class

In addition, the ADK adds a number of custom functions to the ones defined by JXPath. These functions are available in the "adk" namespace and be used by prefixing the function name with "adk:". The ADK functions consist of all of the static members of the ADKFunctions class.

Here is an example of using the toUpperCase() function:

 <blockquote>
  ADK.initialize();
  StudentPersonal student = new StudentPersonal();
  student.setRefId( ADK.makeGUID() );
  EmailList el = new EmailList();
  el.add( new Email( EmailType.PRIMARY, "tjohnson@schools.k12.state.country" ) );
  el.add( new Email (EmailType.ALT1, "RoadRunner@aol.com" ) );
  student.setEmailList( el );
  SIFXPathContext context = SIFXPathContext.newSIFContext( student );
  String value = (String)context.getValue( "adk:toUpperCase(//Email[@Type='Primary'])" );
  System.out.println( "Email: " + value );
 

Defining and using your own custom functions

You can define your own functions using JXPath function objects. To use them with SIFXPathContext, call the registerCustomFunctions(Functions) method.

Version:
ADK 2.0

Field Summary
 
Fields inherited from class org.apache.commons.jxpath.ri.JXPathContextReferenceImpl
USE_SOFT_CACHE
 
Method Summary
static org.apache.commons.jxpath.CompiledExpression compile(java.lang.String legacyXPath)
           
static java.lang.String convertLegacyXPath(java.lang.String xPath)
          Removes XPath syntax that was proprietary to the ADK in ADK 1.x versions and converts the expression to the syntax supported by JXPath
 org.apache.commons.jxpath.Pointer createPath(java.lang.String xpath, org.apache.commons.jxpath.ri.compiler.Expression expr)
           
 org.apache.commons.jxpath.Pointer createPathAndSetValue(java.lang.String xpath, org.apache.commons.jxpath.ri.compiler.Expression expr, java.lang.Object value)
           
 Element getElementOrAttribute(java.lang.String xPath)
          Allows for getting Elements from a SIF Element using the legacy ADK 1.x style XPath queries.
static SIFXPathContext newSIFContext(SIFElement sdo)
          Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object
static SIFXPathContext newSIFContext(SIFElement sdo, SIFVersion version)
          Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object
static SIFXPathContext newSIFContext(SIFXPathContext parent, SIFElement sdo)
          Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object
static SIFXPathContext newSIFContext(SIFXPathContext parent, SIFElement sdo, SIFVersion version)
          Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object
static void registerCustomFunctions(org.apache.commons.jxpath.Functions functions)
          Register custom functions to be used with SIFXPathContext
 void setElementOrAttribute(java.lang.String xPath, java.lang.Object value)
           
 
Methods inherited from class org.apache.commons.jxpath.ri.JXPathContextReferenceImpl
addNodePointerFactory, allocateConditionally, createPath, createPathAndSetValue, getAbsoluteRootContext, getContextPointer, getFunction, getNamespaceContextPointer, getNamespaceResolver, getNamespaceURI, getNodePointerFactories, getPointer, getPointer, getRelativeContext, getValue, getValue, getValue, getValue, getVariablePointer, iterate, iterate, iteratePointers, iteratePointers, registerNamespace, removeAll, removeAll, removePath, removePath, setNamespaceContextPointer, setValue, setValue
 
Methods inherited from class org.apache.commons.jxpath.JXPathContext
getContextBean, getDecimalFormatSymbols, getFactory, getFunctions, getIdentityManager, getKeyManager, getLocale, getParentContext, getPointerByID, getPointerByKey, getVariables, isLenient, newContext, newContext, selectNodes, selectSingleNode, setDecimalFormatSymbols, setFactory, setFunctions, setIdentityManager, setKeyManager, setLenient, setLocale, setVariables
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

newSIFContext

public static SIFXPathContext newSIFContext(SIFElement sdo)
Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object

Parameters:
sdo - The SIF Data Object or SIFElement to traverse
Returns:
an instance of SIFXPathContext

newSIFContext

public static SIFXPathContext newSIFContext(SIFElement sdo,
                                            SIFVersion version)
Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object

Parameters:
sdo - The SIF Data Object or SIFElement to traverse
version - The SIFVersion to use when traversing this object using XPath. NOTE: The SIFDataObject.setSIFVersion(version) is automatically called and set to the target version.
Returns:
an instance of SIFXPathContext

newSIFContext

public static SIFXPathContext newSIFContext(SIFXPathContext parent,
                                            SIFElement sdo)
Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object

Parameters:
parent - the parent context to retrieve settings from
sdo - The SIF Data Object or SIFElement to traverse
Returns:
an instance of SIFXPathContext

newSIFContext

public static SIFXPathContext newSIFContext(SIFXPathContext parent,
                                            SIFElement sdo,
                                            SIFVersion version)
Creates a new SIFXPathContext instance to use for traversing the specified SIF Data Object

Parameters:
parent - the parent context to retrieve settings from
sdo - The SIF Data Object or SIFElement to traverse
version - The SIFVersion to use when traversing this object using XPath. NOTE: The SIFDataObject.setSIFVersion(version) is automatically called and set to the target version.
Returns:
an instance of SIFXPathContext

registerCustomFunctions

public static void registerCustomFunctions(org.apache.commons.jxpath.Functions functions)
Register custom functions to be used with SIFXPathContext

Parameters:
functions -

convertLegacyXPath

public static java.lang.String convertLegacyXPath(java.lang.String xPath)
Removes XPath syntax that was proprietary to the ADK in ADK 1.x versions and converts the expression to the syntax supported by JXPath

Parameters:
xPath - The path to evaluate
Returns:
The converted xPath

compile

public static org.apache.commons.jxpath.CompiledExpression compile(java.lang.String legacyXPath)

getElementOrAttribute

public Element getElementOrAttribute(java.lang.String xPath)
Allows for getting Elements from a SIF Element using the legacy ADK 1.x style XPath queries. This method should only be used if the XPath syntax needs to be converted from ADK 1.x syntax to true XPath. If the query is already in true XPath format, call JXPathContext.getValue(java.lang.String)

Parameters:
xPath -
Returns:
An Element from this object representing the path, or null

setElementOrAttribute

public void setElementOrAttribute(java.lang.String xPath,
                                  java.lang.Object value)

createPathAndSetValue

public org.apache.commons.jxpath.Pointer createPathAndSetValue(java.lang.String xpath,
                                                               org.apache.commons.jxpath.ri.compiler.Expression expr,
                                                               java.lang.Object value)
Overrides:
createPathAndSetValue in class org.apache.commons.jxpath.ri.JXPathContextReferenceImpl

createPath

public org.apache.commons.jxpath.Pointer createPath(java.lang.String xpath,
                                                    org.apache.commons.jxpath.ri.compiler.Expression expr)
Overrides:
createPath in class org.apache.commons.jxpath.ri.JXPathContextReferenceImpl


Copyright © 2001-2007 Edustructures LLC. All Rights Reserved. SIFWorks® and ADK® are registered trademarks of Edustructures LLC. SIF™ and Schools Interoperability Framework are trademarks of the Schools Interoperability Framework Association.