Generic XML Api Snippet

Generic XML Api Snippet

This page is a proof of concept for XML based api. It is meant to be used programmaticaly by web service providers who wish to syndicate, encapsulate or offer an alternative interface.

This API hides classes under XWiki. for security reasons

The page expects calls of the form:
genericXML?xpage=rdf[&targetClass=[classname]][&targetObject=[objectName]][&fields=[field1,flield2,..]][&list=true]][&getScheme=true]]
Where:
  • xpage=rdf: if set, produce xml. if missing, produce a form and brief help text.
  • targetClass: if specified, query only this class
  • targetObject: if specified, query only this object
  • fields: comma separated list of fields to display. if empty, display all.
  • list: list only, display object names only.
  • getScheme: display scheme, i.e. list classes and property names
A potential client could call
genericXML?xpage=rdf&getScheme=true
To list all classes,

Then call

genericXML?xpage=rdf&targetClass=SomeClass&list=true
To list objects of a particular class Then call
genericXML?xpage=rdf&targetClass=SomeClass&targetObject=SomeObject&fields=field1,flield2
To retrieve field1 and field2 of object SomeObject from class SomeClass

Human clients who reach the page are displayed with a brief human-readable explanation, and a form to activate the API.

Of course, this is just an example. You may prefer a different scheme, for example - having a single structure for all objects.

#######
## print class structure, as:
## <class id="ClassName">
##   <property>Property1Name</property>
##   <property>Property2Name</property>
## </class>
#######
#macro(printClass $class)
## Hide system classes
#if(!$class.startsWith("XAppClasses") && !$class.startsWith("XWiki"))
 <class id="$class">
  #set ($properties = $xwiki.getClass($class).getProperties())
  #foreach($property in $properties)
  <property>$property.getName()</property>
  #end
 </class>
#end ## Hide system classes
#end ##printclass
#######
## if the request has "?xpage=rdf", produce XML otherwise, produce html.
## this is a hack, relying on the fact that XWiki skips the skin for  "?xpage=rdf"
#######
#if($request.xpage == "rdf")
$response.setContentType("text/xml")
<xml>
#if($request.targetClass && ($request.targetClass.length() > 2))
  #set ($className = $request.targetClass)
#end
## Hide system classes
#if(!$class.startsWith("XAppClasses") && !$class.startsWith("XWiki"))
#if($request.getScheme) ## get scheme
  #if($className)
     #printClass($className)
  #else
     #set ($classes = $xwiki.getClassList())
     #foreach ($class in $classes)
        #printClass($class)
     #end
  #end
#else  ## get data
#if(!$className) 
  #set ($className = 'Blog.BlogCategories')                   ## random default, just to make life easier.
#end
#if($request.fields && $request.fields.length() > 0)
#set($fields = $request.fields.split(","))                    ## parse field1,field2,…
#end
#if($request.targetObject && $request.targetObject.length() > 0)
#set($objName = $request.targetObject)
#end
#if($request.list)
  #set($listOnly = true)
#end
### get scheme?
#set ($hql = ", BaseObject as obj where obj.name=doc.fullName and obj.className='${className}' and obj.name<>'${className}Template'")
#if($objName)
#set ($hql = $hql+" and obj.name='$objName'")                 ## if object name specified, add it to the query. 
#end                                                          ## a bit lazy here.
#set ($items= $xwiki.searchDocuments($hql))
#if ($items.size() > 0)
#foreach ($item in $items)
   #set ($itemDoc = $xwiki.getDocument($item)
   #set ($itemObj = $itemDoc.getObject("$className"))
   <$className name="$item" url="itemDoc.getURL()">         ## print object opening tag
   #set($class = $itemObj.xWikiClass)
      #if($fields)                                          ## specific fields requested, so ignore "list" mode
         #foreach($field in $fields)
            #set($fieldVal  = $itemObj.get($field))
            <$field>$fieldVal</$field>                      ## print property
         #end
      #else
         #if(!$listOnly)                                    ## if list mode - skip properties
           #foreach($prop in $class.properties)
             #set($propName = $prop.getName())
             #set($propValue  = $itemObj.get($propName))    ## print property
             <$propName>$xwiki.getXMLEncoded(${propValue})</$propName>
          #end
        #end
      #end
   </$className>                                            ## close object
#end
#end
#end ## if: get scheme
#end ## if: Hide system classes
</xml>
#else                                        ## not $request.xpage == "rdf", print form for humans
<form action="">
<input type="hidden" name="xpage" value="rdf" />
Class:
<input type="text" name="targetClass" size="10" />
Object:
<input type="text" name="targetObject" size="10" />
Fields:
<input type="text" name="fields" size="20" /><br/>
List objects<input type="checkbox" name="list" value="true" />
Show scheme<input type="checkbox" name="getScheme" value="true" />
<input type="submit" />
</form>

The expected syntax for an API call is:

*\{code\}http://patternlanguagenetwork.myxwiki.org/xwiki/bin/view/api/genericXML?xpage=rdf[&targetClass=[classname]][&targetObject=[objectName]][&fields=[field1,flield2,..]][&list=true]][&getScheme=true]]\{code\}* * *xpage=rdf*: if set, produce xml. if missing, produce this form. * *targetClass*: class to export, default is Patterns.PatternsClass * *targetObject*: if specified, query only this object * *fields*: comma separated list of fields to display. if empty, display all. * *list*: list only, display object names only. * *getScheme*: display scheme, i.e. list classes and property names

#end

Tags:
Created by Yishay Mor on 2008/12/19 03:33
Last modified by Yishay Mor on 2008/12/23 02:36

This wiki is licensed under a Creative Commons license
2.3.28624