Friday, March 18, 2011

Editorial: Tablets in the Public Sector - Part 1

As 2011 has been termed by some in the media as "The Year of the Tablet," (Fox, CIO & NYT) this is the first part in a series of articles meant to articulate the role Tablet PC's could potentially take in the Public Sector and how our NIEM community might react to this trend. 

While not directly related to Schematron or XSLT, we would be remiss in ignoring modern trends in our application of these technologies.  The fact is, that unless our tools and technologies are adapted to support these trends, they risk being left behind.

This first article will focus on the Tablet and the various roles it can potentially take in the Public Sector.  Some in the media have simply divided the device's role into two oversimplified categories of Content Creation and Content Consumption.  While it is true, devices of any type can do these two things to differing degrees, it is probably easier to understand Tablet technologies in terms of actual public sector environment use cases.

In the Boardroom

In meetings the Tablet most often replaces the paper meeting handouts.  In one large city they estimated that over $1m per year could be saved in paper and printing costs by simply eliminating meeting handouts in favor of electronic meeting materials.  An electronic medium also makes it easy to store, preserve and reexamine materials presented at a later date or by those not who were unable to physically attend the meeting.

An example of where this use case is already becoming a reality is in the NLETS board, where each of the board members is issued a tablet upon which they are provided meeting materials and access to any other critical information prior to and during each meeting.

It is also possible for the Tablet to take the role of the "notebook" or the medium where one takes notes about the meeting, however more often than not, the lack of a stylus or even keyboard (barring separate accessories) for rapid data entry makes this impractical at this point in time.

Current Advantages

Current Disadvantages

- Size & Weight
- Paper Cost Savings
- Ease of Later Referencing
- Ease of Real-Time Update
- Poor Annotation Capabilities

In the Courtroom

There are a number of situations where paper was the predominant medium for hundreds of years only to very recently be replaced with more electronic options.  In the late 1990's, attorney's began to adopt Notebook PC's yet they have never been fully accepted in that environment.  Many courtrooms were never built with a PC in mind therefore the lack of power outlets, desk space and network connectivity quickly became impediments. 

With the advent of Tablet technology, there is a renewed interest in this technology by defense and prosecution alike.  An example trial was recently documented by the Mac Litigator where it highlighted the use of an Tablet in a four day Jury Trial.  Many of the issues with a laptop are overcome by the use of an unobtrusive, always connected, long-lasting Tablet. 

Current Advantages

Current Disadvantages

- Size & Desk Footprint
- Paper Cost Savings
- Battery Life
- Real-Time Updates
- Real-Time Reference
- Poor Data Input Capabilities
- Possible Courtroom Distraction
- Enterprise Security Risk

In the Field

The public sector employs a large number of individuals involved in on-site investigations of various kinds.  Whether it is the city building inspector, a fire marshal or a police detective, they all have similar needs to gather and process data in the field.  For years now, investigators of this kind have been using laptop computers to address this need, however this technology has always been relegated to the car or the office as it would get in the way of the investigator at the work site.  Tablets seem to fit this niche well as their size, weight and connectivity is better suited to the job.

Some agencies are already beginning to investigate and adopt Tablet technology in this manner.  The Knox County Sheriff replaced a number of their detectives' laptops with Tablets as described by an article on the NLETS website

Wireless Tablet technology coupled with GPS, maps and satellite imagery makes Tablets extremely relevant to those public sector employees working in the construction field.  With a Tablet, a building inspector or DOT foreman can walk onto a job site and determine where there may be troubles quickly and easily.  These can also give real-time access to building codes and municipal ordnances as well as architectural images, plans and blueprints.

Current Advantages

Current Disadvantages

- Size & Weight
- Real-Time Reference
- Real-Time Transmission
- Hardware Price Point
- Poor Data Input Capabilities
- Lack of "Rugged" Models
- Enterprise Security Risks

In the Classroom

It seems like whenever the topic of Tablets or eBooks is brought up, a spotlight is placed on the classroom and the typical college student hefting around hundreds of pounds worth of textbooks.  While on the surface and in 10 second sound bites, this makes sense; the classroom setting has experienced significant struggles making Tablets and eBooks a reality in the classroom.  A recent article by the Chronicle for Higher Learning points out a number of the difficulties experienced across several different institutions. 

Regardless of the problems currently being experienced, as the they are addressed, the classroom is a very likely place for Tablet technology to take a strong future foothold.  As a Melbourne Trinity College study points out, even with the disadvantages, the usage of Tablets are still expected to increase at the University level in the upcoming years.

Current Advantages

Current Disadvantages

- Real-Time Learning Feedback
- Size & Weight
- Battery Life
- Hardware Price Point
- eTextbook Prices Still High
- Poor Annotation Capabilities
- Potential Classroom Distraction


In summary, Tablets can be seen and used in a number of environments within the public sector and one should not be surprised as they begin to become less of a consumer toy and more of an industry tool. 

Please bear in mind that we fully acknowledge that the editorial opinions stated in the article above are based on industry generalizations and we fully understand that for every generalization or rule there is an exception. 

Friday, October 29, 2010

Editorial: Growing Support for Asynchronous Transactions

It's always exciting to see a prediction come true. . .especially when its one of your own.  For a number of years now it has been obvious that the simple synchronous web services taught in books and college courses were never going to be sufficient enough to support the highly complex transactions required in the real world.  In particular, transactions which require two-phase validation, such as those that leverage Schematron in addition to simple XML Schema validation.

It appears that others are leaning towards agreeing with this same premise.  Microsoft is now publishing its Visual Studio Async in order to better handle these sorts of highly complex transactions which require higher network latency than your traditional synchronous request/response web service.  Infoworld has a good article here that describes Microsoft's adoption of this new trend.

While not endorsing any specific platform, Microsoft's development tools have historically been a great indicator of market trends.  This latest addition proves to be a good sign that the industry is headed towards better support of this highly complex transaction processing world in which we live.

Wednesday, October 20, 2010

XSLT: Transform XML into nc:ContactInformation Structure

This is a short post to show how to leverage XSLT to convert a simple and generic XML file into NIEM-conformant XML as it pertains to the nc:ContactInformation block. 

This is a very common situation where a "non-NIEM" data stream is received and needs to be converted to a conformant structure.  Take the following sample non-NIEM XML instance:

<?xml version="1.0" encoding="UTF-8" ?>     
<SomeBatchOfStuff>
   <Person>
       <Name>John Doe</Name>
       <PhoneNumber>212-111-2222</PhoneNumber>
   </Person>
   <Person>
       <Name>Sally Smith</Name>
       <PhoneNumber>212-333-4444</PhoneNumber>
   </Person>
</SomeBatchOfStuff>

If this very logical structure needed to be converted into nc:Person and nc:ContactInformatoin elements (with an nc:PersonContactInformationAssociation object to link the two together), the following XSLT could be used:

<?xml version="1.0" encoding="UTF-8" ?>     
<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns0="SomeNonConformantDocumentNamespace" version="1.0" exclude-result-prefixes="xs">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:variable name="var1_instance_InputSchema" select="."/>
        <MyNIEMConformantDocument xmlns="MyNIEMDocumentNamespace" xmlns:i="http://niem.gov/niem/appinfo/2.0" xmlns:nc="http://niem.gov/niem/niem-core/2.0" xmlns:niem-xsd="http://niem.gov/niem/proxy/xsd/2.0" xmlns:s="http://niem.gov/niem/structures/2.0">
            <!-- Loop through the Persons and create an NIEM Conformant Person -->
            <xsl:for-each select="$var1_instance_InputSchema/SomeBatchOfStuff/Person">
                <xsl:variable name="NonConformantPerson" select="."/>
                <nc:Person>
                    <xsl:attribute name="s:id">
                        <xsl:value-of select="generate-id(.)"/>
                    </xsl:attribute>
                    <nc:PersonName>
                        <xsl:for-each select="$NonConformantPerson/Name">
                            <nc:PersonFullName>
                                <xsl:value-of select="string(.)"/>
                            </nc:PersonFullName>
                        </xsl:for-each>
                    </nc:PersonName>
                </nc:Person>
            </xsl:for-each>
            
            <!-- Loop through the phone numbers and create a NIEM Conformant Contact Information -->
            <xsl:for-each select="$var1_instance_InputSchema/SomeBatchOfStuff/Person/PhoneNumber">
                <nc:ContactInformation>
                    <xsl:attribute name="s:id">
                        <xsl:value-of select="generate-id(.)"/>
                    </xsl:attribute>
                    <nc:ContactTelephoneNumber>
                        <nc:FullTelephoneNumber>
                            <nc:TelephoneNumberFullID>
                                <xsl:value-of select="string(.)"/>
                            </nc:TelephoneNumberFullID>
                        </nc:FullTelephoneNumber>
                    </nc:ContactTelephoneNumber>
                </nc:ContactInformation>
            </xsl:for-each>
            
            <!-- Loop through the phone numbers and create a NIEM Conformant Contact Information Association -->
            <xsl:for-each select="$var1_instance_InputSchema/SomeBatchOfStuff/Person">
                <nc:PersonContactInformationAssociation>
                    <nc:PersonReference>
                    <xsl:attribute name="s:ref">
                        <xsl:value-of select="generate-id(.)"/>
                    </xsl:attribute>
                    </nc:PersonReference>
                    <nc:ContactInformationReference>
                        <xsl:attribute name="s:ref">
                            <xsl:value-of select="generate-id(./PhoneNumber)"/>
                        </xsl:attribute>
                    </nc:ContactInformationReference>
                </nc:PersonContactInformationAssociation>
            </xsl:for-each>
        </MyNIEMConformantDocument>
    </xsl:template>                    
</xsl:stylesheet>

The XSLT heavily leverages the XSLT generate-id() function in order to work its magic and result in the following NIEM-conformant XML file:

<?xml version="1.0" encoding="UTF-8" ?>   
<MyNIEMConformantDocument xmlns="MyNIEMDocumentNamespace" xmlns:i="http://niem.gov/niem/appinfo/2.0" xmlns:nc="http://niem.gov/niem/niem-core/2.0" xmlns:niem-xsd="http://niem.gov/niem/proxy/xsd/2.0" xmlns:s="http://niem.gov/niem/structures/2.0" xmlns:ns0="SomeNonConformantDocumentNamespace">
   <nc:Person s:id="d0e3">
      <nc:PersonName>
         <nc:PersonFullName>John Doe</nc:PersonFullName>
      </nc:PersonName>
   </nc:Person>
   <nc:Person s:id="d0e12">
      <nc:PersonName>
         <nc:PersonFullName>Sally Smith</nc:PersonFullName>
      </nc:PersonName>
   </nc:Person>
   <nc:ContactInformation s:id="d0e8">
      <nc:ContactTelephoneNumber>
         <nc:FullTelephoneNumber>
            <nc:TelephoneNumberFullID>212-111-2222</nc:TelephoneNumberFullID>
         </nc:FullTelephoneNumber>
      </nc:ContactTelephoneNumber>
   </nc:ContactInformation>
   <nc:ContactInformation s:id="d0e17">
      <nc:ContactTelephoneNumber>
         <nc:FullTelephoneNumber>
            <nc:TelephoneNumberFullID>212-333-4444</nc:TelephoneNumberFullID>
         </nc:FullTelephoneNumber>
      </nc:ContactTelephoneNumber>
   </nc:ContactInformation>
   <nc:PersonContactInformationAssociation>
      <nc:PersonReference s:ref="d0e3"/>
      <nc:ContactInformationReference s:ref="d0e8"/>
   </nc:PersonContactInformationAssociation>
   <nc:PersonContactInformationAssociation>
      <nc:PersonReference s:ref="d0e12"/>
      <nc:ContactInformationReference s:ref="d0e17"/>
   </nc:PersonContactInformationAssociation>
</MyNIEMConformantDocument>

Wednesday, March 31, 2010

Schematron: Supporting Form Validation in a Data Validation World

NIEM is for all intents and purposes a highly object-oriented data model which may, or may not be used by form entry tools at the time of data capture.  While this has enormous benefits, it can be detrimental if one wants to use Schematron for BOTH form and data validation in conjunction with NIEM.

In order to properly support form validation, source systems will often want to know exactly which field caused an error during the processing of business rules surrounding a form. While in many systems, the map between the source fields and the NIEM may be readily available, in cases where it is not or processing speed is critical, the data validation engine should be capable of furnishing this information back to the calling system.

Lets take the example of a citation data capture tool with the following example data entry UI:

image

NIEM supports the passing of a “footnote” on every element called the nc:Metadata element.  nc:Metadata is a complex data type that in turn includes an element to store the source-system’s field name called nc:SourceIDText.  The NIEM conformant XML instance to pass this would look something like the following:

<ns:CitationBatchDocument> 
  ...
  ...
  ...
  <ns:Citation> 
    ...
    ...
    <!-- Citation Number --> 
    <nc:ActivityIdentification> 
      <nc:IdentificationID s:metadata=”M1”>ABC123</nc:IdentificationID> 
    </nc:ActivityIdentification> 
    <!-- Citation Date --> 
    <nc:ActivityDate> 
      <nc:Date s:metadata=”M2”>2002-05-30</nc:Date> 
    </nc:ActivityDate> 
    ...
    ...
  </ns:Citation> 
  ...
  ...
  ...
  <nc:Metadata s:id=”M1”> 
    <nc:SourceIDText>CITE_NUM</nc:SourceIDText> 
  </nc:Metadata> 
  <nc:Metadata s:id=”M2”> 
    <nc:SourceIDText>CITE_DATE</nc:SourceIDText> 
  </nc:Metadata> 
  ...
  ...
</ <ns:CitationBatchDocument>

While passing the field name to the business rules engine is 1/2 the battle, one must also return the field name with any errors the data validation engine runs into.  An example Schematron code snippet to support returning the field name to the source system in the diagnostics would appear something like the following:

...
...
...
<pattern id="eBasicCiteRules">
  <title>Check the minimum basic citation rules.</title>
  <rule context="cite:CitationBatchDocument/cite:Citation">
    <let name="CiteNumSource" value="/cite:CitationBatchDocument
                                     /nc:Metadata [@s:id = current()
                                     /nc:ActivityIdentification
                                     /nc:IdentificationID/@s:metadata]
                                     /nc:SourceIDText"/>
    <assert test="nc:ActivityIdentification/nc:IdentificationID and
        string-length(normalize-space (nc:ActivityIdentification/nc:IdentificationID))
        &gt; 0" diagnostics="eCiteIdDiag">
            Citations must have a Citation Number.
    </assert>
  </rule>
</pattern>
...
...
...
<diagnostics>
  <diagnostic id="eCiteIdDiag">
    |<value-of select=”@CiteNumSource”/>|
    Some technical error description goes here (e.g. XPath to error).
  </diagnostic>
</diagnostics>

What this will yield to the end user is the following error message:

Citations must have a Citation Number.

What the source system will also receive in the case of any errors would look like the following:

|CITE_NUM| Some technical error description goes here (e.g. XPath to error).

The field name passed back could then be used by the source system in helping guide end users to complete the form correctly (e.g. jump to the first field with an error).  In the above example, simple “bar” delimiters are being used (|) but this could of course be changed to proper XML elements through the use of &gt; and $lt; instead.

EDITED 2010-04-01: Adding current() to XPath in Schematron code snippet.

Thursday, February 11, 2010

XSLT: Using the generate-id() Function

NIEM utilizes ID and IDREF elements heavily throughout the data standard.  While this is native to the W3C specification for XML Schema files (.XSD) and in no way “unique” to NIEM, it is used much more heavily in NIEM than in many other national and international standards. 

When converting or transforming to NIEM from another data standard, it quickly becomes necessary to generate unique identifiers in a common and consistent manner for key “noun” elements such as Persons, Places, Vehicles, and the like.  A number of home-grown functions are scattered around the Internet to do this, however a native XSLT function already exists to perform this task called generate-id()

Say the following non-NIEM-conformant XML payload is provided to a system processing citation data:

<CitationBatch>
  <Citation>
    <CitationNumber>123456</CitationNumber>
    <CitationDefendant>
      <FirstName>John</FirstName>
      <LastName>Doe</LastName>
      <PhoneNumber>123-456-7890</PhoneNumber>
    </CitationDefendant>
    <!-- Remainder Omitted -->
  </Citation>
<CitationBatch>

Within NIEM the <CitationDefendant> element above is termed the <j:CitationSubject> and includes a <nc:RoleOfPersonReference> rather than embedding all person information as child elements within the citation.  Additionally, the phone number for any given person is contained within a <nc:ContactInformation> element. 

The XSLT generate-id() function accepts a specific xml node as its input parameter and will consistently provide a unique ID for that node no matter where or how many times it is called from within the XSLT.  For example, take the following XSLT snippets:

<xsl:for-each select="$xmlInputFile/CitationBatch/Citation">
        <xsl:variable name="xmlCiteNode" select="."/>
        <j:CitationSubject>
            <nc:RoleOfPersonReference>
                <xsl:attribute name="s:ref">
                    <xsl:value-of select="generate-id($xmlCiteNode/CitationDefendant)"/>
                </xsl:attribute>
            </nc:RoleOfPersonReference>
        </j:CitationSubject>
    </xsl:for-each>
    ....
    ....
    ....
    <xsl:for-each select="$xmlInputFile/CitationBatch/Citation/CitationDefendant">
        <xsl:variable name="xmlCiteSubjectNode" select="."/>
        <nc:Person>
            <xsl:attribute name="s:id">
                <xsl:value-of select="generate-id($xmlCiteSubjectNode)"/>
            </xsl:attribute>
        </nc:Person>
    </xsl:for-each>
    ....
    ....

Even though the generate-id() function is called in two places within the transform, using two different variable names, the function will return the same exact yet unique ID as the XPath for both variables resolve to the same element in the input schema.  The output of the above would appear as the following:

....
....
<j:CitationSubject>
    <nc:RoleOfPersonReference s:ref="d0e8"/>
</j:CitationSubject>
....
....
<nc:Person s:id="d0e8"/>

This powerful function within XSLT dramatically ease ID and IDREF usage within XML and makes implementation of transforms to NIEM relatively trivial.

Monday, January 11, 2010

XSLT: Transform Date and Time Elements into nc:DateTime

While NIEM practitioners tend to merge Date and Time elements together into single nc:DateTime elements, we often find that the outside world separates these into two fields in their XML data packages.  For example, if someone were to use Java XForms or Microsoft InfoPath to capture data in an electronic form, it is common to separate these out into their component parts.

For example, assume a NIBRS report form exists and has discrete date and time values.  Using XSLT to merge these is quite simple and can be done using the concat() function as show here:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="SomeNibrsOffenseReportNamespace"
    exclude-result-prefixes="ns">
    
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:variable name="sInputSchema" select="."/>
        
        <OffenseReportDocument xmlns="SomeNiemOffenseReportNamespace" xmlns:j="http://niem.gov/niem/domains/jxdm/4.0" xmlns:nc="http://niem.gov/niem/niem-core/2.0">
          <j:Offense>
            <nc:ActivityDate>
              <nc:DateTime>
                <xsl:value-of select="concat(string($sInputSchema/ns:NibrsForm/ns:OffenseDate), 'T', string(sInputSchema/ns:NibrsForm/ns:OffenseTime))"/>
              </nc:DateTime>
            </nc:ActivityDate>
          </j:Offense>
        </OffenseReportDocument>
    </xsl:template>
</xsl:stylesheet>

In the above example, the concat() function allows us to merge the date (e.g. ‘2010-01-01’), the letter ‘T’, and the time (e.g. ‘12:00:00’) into a single string which in turn can be evaluated as a nc:dateTime element. 

1-13-10 – Edit for typo

Thursday, January 7, 2010

Schematron: Using the Number() Function Versus Casting

There are situations where it becomes necessary to test the value of a numeric element to ensure it meets some minimum or maximum value.  As Schematron is capable of treating any element as a string, it is generally a best practice to cast the value to a numeric data type first. 

For example, on a citation or a complaint document it may be necessary to check the fine or bail amount to ensure it is greater than zero.  This could be done with the following Schematron assert statement:

<assert test="xsd:double(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be less than zero.
</assert>

While the above would work when a value is provided in the nc:ObligationDueAmount element, an XSLT error would be raised in the following circumstances:

  • Value is blank or null
      • <nc:ObligationDueAmount></nc:ObligationDueAmount>
  • Value is omitted
      • <nc:ObligationDueAmount/>
  • Value is a string value
      • <nc:ObligationDueAmount>N/A</nc:ObligationDueAmount>

For this reason, it is often preferable to use the native XPath function number().  As described by Ms. Priscilla Walmsley in her O’Reilly book XQuery, this function will prevent the XSLT parser from throwing an error and instead return the value ‘NaN’ (Not a Number).  The following would be the same way the Schematron test could be written using the number() function instead:

<assert test="number(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be less than zero.
</assert>
<assert test="nc:ObligationDueAmount and string-length(nc:ObligationDueAmount) &gt; 0">
  Bail amount may not be left blank or otherwise omitted.
</assert>

While a few more lines are required, this prevents a runtime parser error from being raised and causing havoc with the validation engine.