# metadata_convert.pl

# This script prototypes the conversion that should be handled
# by the NSDL-LONCAPA gateway.

# Scott Harrison 2002

# For nicely viewable documentation, execute the following command:
# ./perldoc metadata_convert.pl

# =========================================================== POD documentation

=pod

=head1 NAME

metadata_convert.pl - prototype metadata conversion for NSDL-LONCAPA gateway

=head1 SYNOPSIS

Usage: perl metadata_convert.pl

There is no input to this script.  The output of this script
will describe the success or failure of the metadata conversion that happens.

The script is organized into the following sections:

=over 4

=item POD documentation

=item Initial settings for the script

=item Defining test XML metadata input

=item Define XSL stylesheets

=item Define external functions

=item Executing transformations

=item Various subroutines

=back

=head1 DESCRIPTION

This script converts LON-CAPA metadata into NSDL metadata
and converts NSDL metadata into LON-CAPA metadata.

Example metadata strings are included in this prototype
script--they are named by variables such as
I<$LONCAPA_metadata> and I<$NSDL_metadata>.

The XML-processing "engine" for the transformation is B<XML::Xalan>
available at http://search.cpan.org/search?dist=XML-Xalan.  This engine
takes in XML files of one DTD type and converts them into XML
files of another DTD type according to stylesheets.

 alpha.xml      alpha_to_beta.xsl   beta.xml
 (alpha.dtd)    ---------------->   (beta.dtd)

LON-CAPA metadata currently consists of 13 different metadata fields
(with defined datatypes):
abstract, author, copyright, creationdate, dependencies, keywords, language,
lastrevisiondate, mime, notes, owner, subject, and title.

For purposes of the gateway implementation, I am defining a qualified LON-CAPA
metadata to consist of additional fields (which can be automatically
generated from information on the LON-CAPA network):

"uri", which is both the address and unique identifier of the educational
resource from the standpoint of LON-CAPA.

"structure", which is derived from the LON-CAPA MIME type of the file

"aggregation", which is derived from the LON-CAPA MIME type of the file

"bytesize", the size of the LON-CAPA resource in bytes (octets)

"version", which comes from information accessed from the LON-CAPA network

"metauri", which comes from the uri (with .meta appended)

In the future, more LON-CAPA metadata fields are expected to be added, and
it may also be that several of the fields change, or are removed.

The current viewpoint regarding NSDL is to support unqualified dublin
core and IEEE LOM, with IEEE LOM being preferred.  Both are to be
supported (dublin core being the minimal and IEEE LOM being the maximal).
There are 15 unqualified
Dublin Core elements.  For version 6.4 of IEEE LOM (March 4, 2002--this is
the version the gateway approach is based off of) there are 77 IEEE LOM
category names with 58 IEEE LOM fields which correspond to a subset of
the 77 category names.  A complete description of IEEE LOM version 6.4
is available at http://ltsc.ieee.org/doc/wg12/LOM_WD6_4.pdf.  Note that
the 15 Dublin Core elements correspond to a subset of the 58 IEEE LOM fields.

A summary (for the sake of brevity, with some details omitted) of how
IEEE LOM and Dublin Core and LON-CAPA interrelate is described below
(column order=LON-CAPA field, IEEE LOM datatype, IEEE LOM field,
and Dublin Core Field).
Note that an asterisk (*) for the LON-CAPA field indicates that a IEEE
LOM field value can probably be generated for
the LON-CAPA to NSDL metadata transformation.  Note that a question mark (?)
indicates that a LOM field value may in the future be generated for
the transformation.  Note that a minus sign (-) indicates that a LOM
field value may not be generated for the transformation in the foreseeable
future (never say absolutely never though).  The mappings below are not
perfectly bidirectional; there are a number of one-to-many and many-to-one
mappings that are involved in the metadata conversion.

                      -                1:General
                      -                1.1:General.Identifier
 lc:*                 CharacterString  1.1.1:General.Identifier.Catalog
 lc:uri               CharacterString  1.1.2:General.Identifier.Entry          DC.Identifier
 lc:title             LangString       1.2:General.Title                       DC.Title
 lc:language          CharacterString  1.3:General.Language                    DC.Language
 lc:abstract          LangString       1.4:General.Description                 DC.Description
 lc:keywords          LangString       1.5:General.Keyword                     DC.Subject
 lc:-                 LangString       1.6:General.Coverage                    DC.Coverage
 lc:structure         VocabularyState  1.7:General.Structure
 lc:aggregation       VocabularyEnum   1.8:General.AggregationLevel
                      -                2:LifeCycle
 lc:version           LangString       2.1:LifeCycle.Version
 lc:?                 VocabularyState  2.2:LifeCycle.Status
                      -                2.3:LifeCycle.Contribute
 lc:*                 VocabularyState  2.3.1:LifeCycle.Contribute.Role
 lc:author            CharacterString  2.3.2:LifeCycle.Contribute.Entity       DC.Creator DC.OtherContributor DC.Publisher
 lc:lastrevisiondate  DateTime         2.3.3:LifeCycle.Contribute.Date         DC.Date
                      -                3:MetaMetadata
                      -                3.1:MetaMetadata.Identifier
 lc:*                 CharacterString  3.1.1:MetaMetadata.Identifier.Catalog
 lc:metauri           CharacterString  3.1.2:MetaMetadata.Identifier.Entry
                      -                3.2:MetaMetadata.Contribute
 lc:?                 VocabularyState  3.2.1:MetaMetadata.Contribute.Role
 lc:?                 CharacterString  3.2.2:MetaMetadata.Contribute.Entity
 lc:?                 DateTime         3.2.3:MetaMetadata.Contribute.Date
 lc:*                 CharacterString  3.3:MetaMetadata.MetadataSchema
 lc:*                 CharacterString  3.4:MetaMetadata.Language
                      -                4:Technical
 lc:mime              CharacterString  4.1:Technical.Format                    DC.Format
 lc:bytesize          CharacterString  4.2:Technical.Size
 lc:uri               CharacterString  4.3:Technical.Location
                      -                4.4:Technical.Requirement
                      -                4.4.1:Technical.Requirement.OrComposite
 lc:?                 VocabularyState  4.4.1.1:Technical.Requirement.OrComposite.Type
 lc:?                 VocabularyState  4.4.1.2:Technical.Requirement.OrComposite.Name
 lc:?                 CharacterString  4.4.1.3:Technical.Requirement.OrComposite.MinimumVersion
 lc:?                 CharacterString  4.4.1.4:Technical.Requirement.OrComposite.MaximumVersion
 lc:?                 LangString       4.5:Technical.InstallationRemarks
 lc:*                 LangString       4.6:Technical.OtherPlatformRequirements
 lc:?                 Duration         4.7:Technical.Duration
                      -                5:Educational
 lc:?                 VocabularyState  5.1:Educational.InteractivityType
 lc:?                 VocabularyState  5.2:Educational.LearningResourceType    DC.Type
 lc:?                 VocabularyEnum   5.3:Educational.InteractivityLevel
 lc:?                 VocabularyEnum   5.4:Educational.SemanticDensity
 lc:*                 VocabularyState  5.5:Educational.IntendedEndUserRole
 lc:?                 VocabularyState  5.6:Educational.Context
 lc:?                 LangString       5.7:Educational.TypicalAgeRange
 lc:?                 VocabularyEnum   5.8:Educational.Difficulty
 lc:?                 Duration         5.9:Educational.TypicalLearningTime
 lc:notes             LangString       5.10:Educational.Description
 lc:language          CharacterString  5.11:Educational.Language
                      -                6:Rights
 lc:-                 VocabularyState  6.1:Rights.Cost
 lc:copyright         VocabularyState  6.2:Rights.CopyrightandOtherRestrictions
 lc:owner             LangString       6.3:Rights.Description                  DC.Rights
                      -                7:Relation
 lc:?                 VocabularyState  7.1:Relation.Kind
                      -                7.2:Relation.Resource                   DC.Source
                      -                7.2.1:Relation.Resource.Identifier
 lc:?                 CharacterString  7.2.1.1:Relation.Resource.Identifier.Catalog
 lc:?                 CharacterString  7.2.1.2:Relation.Resource.Identifier.Entry
 lc:?                 LangString       7.2.2:Relation.Resource.Description     DC.Relation
                      -                8:Annotation
 lc:-                 CharacterString  8.1:Annotation.Entity
 lc:-                 DateTime         8.2:Annotation.Date
 lc:-                 LangString       8.3:Annotation.Description
                      -                9:Classification
 lc:?                 VocabularyState  9.1:Classification.Purpose
                      -                9.2:Classification.TaxonPath
 lc:?                 LangString       9.2.1:Classification.TaxonPath.Source
                      -                9.2.2:Classification.TaxonPath.Taxon
 lc:?                 CharacterString  9.2.2.1:Classification.TaxonPath.Taxon.Id
 lc:?                 LangString       9.2.2.2:Classification.TaxonPath.Taxon.Entry
 lc:?                 LangString       9.3:Classification.Description
 lc:?                 LangString       9.4:Classification.Keyword

=head1 AUTHOR

Scott Harrison, 2002

=cut

# ============================================= Initial settings for the script

use XML::Xalan; # engine for processing XML transformations
use Date::Format;
use Date::Parse;

my $tr = new XML::Xalan::Transformer;

my $namespace='http://nsdl.lon-capa.org/namespace/ExternalFunction/';

# ============================================ Defining test XML metadata input

# -------------------------------------- An example metadata entry for LON-CAPA
my $LONCAPA_metadata=(<<END);
<abstract></abstract>
<author>Felicia Berryman, MSU HHMI First Year Online Biology</author>
<copyright>default</copyright>
<creationdate>1011110523</creationdate>
<dependencies></dependencies>
<keywords>biomolecules,practice</keywords>
<language>seniso</language>
<lastrevisiondate>1011110523</lastrevisiondate>
<mime>html</mime>
<notes></notes>
<owner>bio\@msu, bio\@msu (Michigan State University), bio\@msu (Michigan State University), bio\@msu (Michigan State University)</owner>
<subject>Bio Information, Large Biomolecules - Intro, Large Biomolecules - Review</subject>
<title>Test title</title>
END

# ---------------------------- An example qualified metadata entry for LON-CAPA
my $LONCAPA_qualified_metadata=(<<END);
<?xml version="1.0"?>
<loncapa xmlns="http://nsdl.lon-capa.org/loncapa/elements/1.1/">
<abstract>This is an example abstract.</abstract>
<author>Felicia Berryman, MSU HHMI First Year Online Biology</author>
<copyright>default</copyright>
<creationdate>1011110523</creationdate>
<dependencies></dependencies>
<keywords>biomolecules,practice</keywords>
<language>seniso</language>
<lastrevisiondate>1011110523</lastrevisiondate>
<mime>html</mime>
<notes></notes>
<owner>bio\@msu, bio\@msu (Michigan State University), bio\@msu (Michigan State University), bio\@msu (Michigan State University)</owner>
<subject>Bio Information, Large Biomolecules - Intro, Large Biomolecules - Review</subject>
<title>Test title</title>
<structure>structure</structure>
<aggregation>aggregation</aggregation>
<bytesize>10000</bytesize>
<version>1</version>
<metauri>http://nsdl.lon-capa.org/msu/bio/dir1/res1.html.meta</metauri>
<uri>http://nsdl.lon-capa.org/msu/bio/dir1/res1.html</uri>
</loncapa>
END

my $NSDL_metadata1=(<<END);
<?xml version="1.0"?>
<dc xmlns="http://purl.org/dc/elements/1.1/">
<title>The Cornell Law Quarterly</title>
<date>1915-1916</date>
<identifier>http://heinonline.org/HeinOnline/show.pl?
            handle=hein.journals/clqv1%26id=1%26size=4</identifier>
<rights>Available by Subscription. See http://www.wshein.com</rights>
</dc>
END

my $NSDL_metadata2=(<<END);
<dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Grassmann's space analysis</dc:title> 
<dc:creator>Hyde, E. W. (Edward Wyllys)</dc:creator>
<dc:subject>LCSH:Ausdehnungslehre; LCCN QA205.H99</dc:subject>
<dc:publisher>J. Wiley &amp; Sons</dc:publisher>
<dc:date>Created: 1906; Available: 1991</dc:date>
<dc:type>text</dc:type>
<dc:identifier>http://resolver.library.cornell.edu/math/1796949</dc:identifier>
<dc:language>eng</dc:language>
<dc:rights>Public Domain</dc:rights>
</dc:dc>
END

open(OUT,'>tmp_dcnsdl.xml');
print(OUT <<END);
$NSDL_metadata2
END
close(OUT);

#open(OUT,'>tmp_loncapa.xml');
#print(OUT <<END);
#<?xml version="1.0"?>
#<loncapa>
#$LONCAPA_metadata
#</loncapa>
#END
#close(OUT);

open(OUT,'>tmp_loncapa.xml');
print(OUT <<END);
$LONCAPA_qualified_metadata
END
close(OUT);


my $NSDL_metadata3=(<<END);
<?xml version="1.0"?>
<lom xmlns="http://nsdl.lon-capa.org/lom/elements/6.4/">

  <General>
    <Identifier>
     <Catalog>ISBN</Catalog>
     <Entry>1323-143-d123-23</Entry>
    </Identifier>
    <Title>("en","House of Cards")</Title>
    <Language>en</Language>
    <Keyword>("en","Mona Lisa")</Keyword>
  </General>

  <LifeCycle>
      <Contribute>
        <Role>Creator</Role>
        <Person>Mary Smith</Person>
        <Date>1998-07-20</Date>
      </Contribute>
  </LifeCycle>

  <Meta-metadata>
    <Contribute>
      <Date>1998-07-21</Date>
      <Person>Joe Smith</Person>
      <Organization>ACME Content</Organization>
    </Contribute>
    <Scheme>Base 1.0, IMS, ARIADNE</Scheme>
    <Language>en</Language>
  </Meta-metadata>

  <Technical>
    <Format>HTML</Format>
    <Location>http://www.manta.ieee.org/p1484/somewhere</Location>
    <Requirement>
      <OrComposite>
      <Type>operating system</Type>
      <Name>ms-windows</Name>
      </OrComposite>
    </Requirement>
  </Technical>

  <Rights>
    <CopyrightandOtherRestrictions>yes</CopyrightandOtherRestrictions>
    <Description>("en","Copyright 2002 by A Big Green Elephant")</Description>
  </Rights>

  <Classification>
      <TaxonPath>
        <Source>Standard Architectural Terms</Source>
        <Taxon><Id>321</Id>
               <Entry>("en","Temporary Shelter")</Entry></Taxon>
        <Taxon><Id>322</Id>
               <Entry>("en","A Really Small Tent")</Entry></Taxon>
      </TaxonPath>
  </Classification>

</lom>
END

open(OUT,'>tmp_lomnsdl.xml');
print(OUT <<END);
$NSDL_metadata3
END
close(OUT);

# ====================================================== Define XSL stylesheets

# ------------------------------------------------------- dcnsdl_to_loncapa.xsl
open(OUT,'>dcnsdl_to_loncapa.xsl');
print(OUT <<END);
<?xml version="1.0"?> 
<xsl:stylesheet
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:external="$namespace"
>
<xsl:template match="/">
<loncapa:loncapa
 xmlns:loncapa="http://nsdl.lon-capa.org/loncapa/elements/1.1/">
<xsl:text>
</xsl:text>
<xsl:apply-templates select="/*/dc:identifier"/>
<xsl:apply-templates select="/*/dc:title"/>
<xsl:apply-templates select="/*/dc:language"/>
<xsl:apply-templates select="/*/dc:description"/>
<xsl:apply-templates select="/*/dc:subject"/>
<!-- xsl:apply-templates select="/*/dc:coverage"/ -->
<xsl:apply-templates select="/*/dc:creator"/>
<xsl:apply-templates select="/*/dc:publisher"/>
<xsl:apply-templates select="/*/dc:date"/>
<xsl:apply-templates select="/*/dc:format"/>
<!-- xsl:apply-templates select="/*/dc:type"/ -->
<xsl:apply-templates select="/*/dc:rights"/>
<!-- xsl:apply-templates select="/*/dc:source"/ -->
<!-- xsl:apply-templates select="/*/dc:relation"/ -->
</loncapa:loncapa>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:identifier">
<uri>
         <xsl:choose>
           <xsl:when 
         test="function-available('external:dcnsdl_identifier_to_loncapa_uri')"
             >
             <xsl:value-of select=
                               "external:dcnsdl_identifier_to_loncapa_uri(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:dcnsdl_identifier_to_loncapa_uri() is not available!
           </xsl:otherwise>
         </xsl:choose>
</uri>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:title">
<title>
         <xsl:choose>
           <xsl:when
            test="function-available('external:dcnsdl_title_to_loncapa_title')"
             >
             <xsl:value-of select="external:dcnsdl_title_to_loncapa_title(.)"/>
           </xsl:when>
           <xsl:otherwise>
            Function external:dcnsdl_title_to_loncapa_title() is not available!
           </xsl:otherwise>
         </xsl:choose>
</title>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:language">
<language>
         <xsl:choose>
           <xsl:when
      test="function-available('external:dcnsdl_language_to_loncapa_language')"
             >
             <xsl:value-of select=
                            "external:dcnsdl_language_to_loncapa_language(.)"/>
           </xsl:when>
           <xsl:otherwise>
      Function external:dcnsdl_language_to_loncapa_language() is not available!
           </xsl:otherwise>
         </xsl:choose>
</language>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:description">
<abstract>
         <xsl:choose>
           <xsl:when
   test="function-available('external:dcnsdl_description_to_loncapa_abstract')"
             >
             <xsl:value-of select=
                         "external:dcnsdl_description_to_loncapa_abstract(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:dcnsdl_description_to_loncapa_abstract() is not available!
           </xsl:otherwise>
         </xsl:choose>
</abstract>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:subject">
<subject>
         <xsl:choose>
           <xsl:when
        test="function-available('external:dcnsdl_subject_to_loncapa_subject')"
             >
             <xsl:value-of select=
                              "external:dcnsdl_subject_to_loncapa_subject(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:dcnsdl_subject_to_loncapa_subject() is not available!
           </xsl:otherwise>
         </xsl:choose>
</subject>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:creator">
<author>
         <xsl:choose>
           <xsl:when
        test="function-available('external:dcnsdl_creator_to_loncapa_author')"
             >
             <xsl:value-of select=
                               "external:dcnsdl_creator_to_loncapa_author(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:dcnsdl_creator_to_loncapa_author() is not available!
           </xsl:otherwise>
         </xsl:choose>
</author>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:publisher">
<owner>
         <xsl:choose>
           <xsl:when
        test="function-available('external:dcnsdl_publisher_to_loncapa_owner')"
             >
             <xsl:value-of select=
                              "external:dcnsdl_publisher_to_loncapa_owner(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:dcnsdl_publisher_to_loncapa_owner() is not available!
           </xsl:otherwise>
         </xsl:choose>
</owner>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:date">
<lastrevisiondate>
         <xsl:choose>
           <xsl:when
  test="function-available('external:dcnsdl_date_to_loncapa_lastrevisiondate')"
             >
             <xsl:value-of select=
                        "external:dcnsdl_date_to_loncapa_lastrevisiondate(.)"/>
           </xsl:when>
           <xsl:otherwise>
  Function external:dcnsdl_date_to_loncapa_lastrevisiondate() is not available!
           </xsl:otherwise>
         </xsl:choose>
</lastrevisiondate>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:format">
<mime>
         <xsl:choose>
           <xsl:when
            test="function-available('external:dcnsdl_format_to_loncapa_mime')"
             >
             <xsl:value-of select=
                                  "external:dcnsdl_format_to_loncapa_mime(.)"/>
           </xsl:when>
           <xsl:otherwise>
            Function external:dcnsdl_format_to_loncapa_mime() is not available!
           </xsl:otherwise>
         </xsl:choose>
</mime>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="dc:rights">
<copyright>
         <xsl:choose>
           <xsl:when
       test="function-available('external:dcnsdl_rights_to_loncapa_copyright')"
             >
             <xsl:value-of select=
                             "external:dcnsdl_rights_to_loncapa_copyright(.)"/>
           </xsl:when>
           <xsl:otherwise>
       Function external:dcnsdl_rights_to_loncapa_copyright() is not available!
           </xsl:otherwise>
         </xsl:choose>
</copyright>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
END
close(OUT);

# ------------------------------------------------------- loncapa_to_dcnsdl.xsl
open(OUT,'>loncapa_to_dcnsdl.xsl');
print(OUT <<END);
<?xml version="1.0"?> 
<xsl:stylesheet
  xmlns:loncapa="http://nsdl.lon-capa.org/loncapa/elements/1.1/"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:external="$namespace"
>
<xsl:template match="/">
<dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/">
<xsl:text>
</xsl:text>
<!-- xsl:apply-templates select="/*/loncapa:*"/ -->
<xsl:apply-templates select="/*/loncapa:title"/>
<xsl:apply-templates select="/*/loncapa:author"/>
<xsl:apply-templates select="/*/loncapa:owner"/>
<xsl:apply-templates select="/*/loncapa:subject"/>
<xsl:apply-templates select="/*/loncapa:abstract"/>
<xsl:apply-templates select="/*/loncapa:lastrevisiondate"/>
<xsl:apply-templates select="/*/loncapa:mime"/>
<xsl:apply-templates select="/*/loncapa:uri"/>
<xsl:apply-templates select="/*/loncapa:language"/>
<xsl:apply-templates select="/*/loncapa:copyright"/>
<dc:relation>[unknown]</dc:relation>
<xsl:text>
</xsl:text>
<dc:source>[unknown]</dc:source>
<xsl:text>
</xsl:text>
<dc:coverage>[unknown]</dc:coverage>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="/*/loncapa:copyright"/>
</dc:dc>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:title">
<dc:title>
         <xsl:choose>
           <xsl:when
                 test=
                 "function-available('external:loncapa_title_to_dcnsdl_title')"
             >
             <xsl:value-of select="external:loncapa_title_to_dcnsdl_title(.)"/>
           </xsl:when>
           <xsl:otherwise>
            Function external:loncapa_title_to_dcnsdl_title() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:title>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:author">
<dc:contributor>
         <xsl:choose>
           <xsl:when
                 test=
          "function-available('external:loncapa_author_to_dcnsdl_contributor')"
             >
             <xsl:value-of
                    select="external:loncapa_author_to_dcnsdl_contributor(.)"/>
           </xsl:when>
           <xsl:otherwise>
     Function external:loncapa_author_to_dcnsdl_contributor() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:contributor>
<xsl:text>
</xsl:text>
<dc:creator>
         <xsl:choose>
           <xsl:when
                 test=
              "function-available('external:loncapa_author_to_dcnsdl_creator')"
             >
             <xsl:value-of
                        select="external:loncapa_author_to_dcnsdl_creator(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:loncapa_author_to_dcnsdl_creator() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:creator>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:owner">
<dc:publisher>
         <xsl:choose>
           <xsl:when
                 test=
             "function-available('external:loncapa_owner_to_dcnsdl_publisher')"
             >
             <xsl:value-of
                       select="external:loncapa_owner_to_dcnsdl_publisher(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:loncapa_owner_to_dcnsdl_publisher() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:publisher>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:subject">
<dc:subject>
         <xsl:choose>
           <xsl:when
                 test=
             "function-available('external:loncapa_subject_to_dcnsdl_subject')"
             >
           <xsl:value-of
                       select="external:loncapa_subject_to_dcnsdl_subject(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:loncapa_subject_to_dcnsdl_subject() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:subject>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:abstract">
<dc:description>
         <xsl:choose>
           <xsl:when
                 test=
        "function-available('external:loncapa_abstract_to_dcnsdl_description')"
             >
             <xsl:value-of
                  select="external:loncapa_abstract_to_dcnsdl_description(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:loncapa_abstract_to_dcnsdl_description() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:description>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:lastrevisiondate">
<date>
         <xsl:choose>
           <xsl:when
                 test=
       "function-available('external:loncapa_lastrevisiondate_to_dcnsdl_date')"
             >
             <xsl:value-of select=
                        "external:loncapa_lastrevisiondate_to_dcnsdl_date(.)"/>
           </xsl:when>
           <xsl:otherwise>
  Function external:loncapa_lastrevisiondate_to_dcnsdl_date() is not available!
           </xsl:otherwise>
         </xsl:choose>
</date>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:mime">
<dc:type>
         <xsl:choose>
           <xsl:when
                 test=
                   "function-available('external:loncapa_mime_to_dcnsdl_type')"
             >
             <xsl:value-of select="external:loncapa_mime_to_dcnsdl_type(.)"/>
           </xsl:when>
           <xsl:otherwise>
              Function external:loncapa_mime_to_dcnsdl_type() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:type>
<xsl:text>
</xsl:text>
<dc:format>
         <xsl:choose>
           <xsl:when
                 test=
                 "function-available('external:loncapa_mime_to_dcnsdl_format')"
             >
             <xsl:value-of select="external:loncapa_mime_to_dcnsdl_format(.)"/>
           </xsl:when>
           <xsl:otherwise>
            Function external:loncapa_mime_to_dcnsdl_format() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:format>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:uri">
<dc:identifier>
         <xsl:choose>
           <xsl:when
                 test=
              "function-available('external:loncapa_uri_to_dcnsdl_identifier')"
             >
             <xsl:value-of select=
                               "external:loncapa_uri_to_dcnsdl_identifier(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:loncapa_uri_to_dcnsdl_identifier() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:identifier>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:language">
<dc:language>
         <xsl:choose>
           <xsl:when
                 test=
           "function-available('external:loncapa_language_to_dcnsdl_language')"
             >
             <xsl:value-of select=
                            "external:loncapa_language_to_dcnsdl_language(.)"/>
           </xsl:when>
           <xsl:otherwise>
      Function external:loncapa_language_to_dcnsdl_language() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:language>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:copyright">
<dc:rights>
         <xsl:choose>
           <xsl:when
                 test=
            "function-available('external:loncapa_copyright_to_dcnsdl_rights')"
             >
             <xsl:value-of select=
                            "external:loncapa_copyright_to_dcnsdl_rights(.)"/>
           </xsl:when>
           <xsl:otherwise>
       Function external:loncapa_copyright_to_dcnsdl_rights() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:rights>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
END
close(OUT);

# ------------------------------------------------------ lomnsdl_to_loncapa.xsl
open(OUT,'>lomnsdl_to_loncapa.xsl');
print(OUT <<END);
<?xml version="1.0"?> 
<xsl:stylesheet
  xmlns:lom="http://nsdl.lon-capa.org/lom/elements/6.4/"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:external="$namespace"
>
<xsl:template match="/">
<loncapa:loncapa
 xmlns:loncapa="http://nsdl.lon-capa.org/loncapa/elements/1.1/">
<xsl:text>
</xsl:text>
<xsl:apply-templates select="/*/lom:General/lom:Identifier"/>
<xsl:apply-templates select="/*/lom:General/lom:Title"/>
<xsl:apply-templates select="/*/lom:General/lom:Language"/>
<xsl:apply-templates select="/*/lom:General/lom:Description"/>
<xsl:apply-templates select="/*/lom:General/lom:Keyword"/>
<xsl:apply-templates select="/*/lom:LifeCycle/lom:Contribute"/>
<xsl:apply-templates select="/*/lom:Technical/lom:Format"/>
<xsl:apply-templates select="/*/lom:Technical/lom:Size"/>
<xsl:apply-templates select="/*/lom:Educational/lom:Description"/>
<xsl:apply-templates select="/*/lom:Rights/lom:CopyrightandOtherRestrictions"/>
<xsl:apply-templates select="/*/lom:Rights/lom:Description"/>
</loncapa:loncapa>
</xsl:template>
<xsl:template match="lom:General/lom:Identifier">
<uri>http://nsdl.lon-capa.org/gateres/<xsl:value-of select="lom:Catalog"/>/<xsl:value-of select="lom:Entry"/>
</uri>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:General/lom:Title">
<title>
         <xsl:choose>
           <xsl:when 
    test="function-available('external:lomnsdl_GeneralTitle_to_loncapa_title')"
             >
             <xsl:value-of select=
                          "external:lomnsdl_GeneralTitle_to_loncapa_title(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:lomnsdl_GeneralTitle_to_loncapa_title() is not available!
           </xsl:otherwise>
         </xsl:choose>
</title>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:General/lom:Language">
<language>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:lomnsdl_GeneralLanguage_to_loncapa_language')"
             >
             <xsl:value-of select=
                    "external:lomnsdl_GeneralLanguage_to_loncapa_language(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_GeneralLanguage_to_loncapa_language() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</language>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:General/lom:Keyword">
<keywords>
         <xsl:choose>
           <xsl:when
                 test=
    "function-available('external:lomnsdl_GeneralKeyword_to_loncapa_keywords')"
             >
             <xsl:value-of select=
                     "external:lomnsdl_GeneralKeyword_to_loncapa_keywords(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_GeneralKeyword_to_loncapa_keywords() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</keywords>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:LifeCycle/lom:Contribute">
         <xsl:choose>
           <xsl:when
               test="function-available('external:lomnsdl_LifeCycleContribute_prepare_converter_INFO')"
             >
             <xsl:value-of select=
        "external:lomnsdl_LifeCycleContribute_prepare_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_LifeCycleContribute_prepare_converter_INFO()
is not available!
           </xsl:otherwise>
         </xsl:choose>
<xsl:apply-templates select="/*/lom:LifeCycle/lom:Contribute/lom:Role"/>
<xsl:apply-templates select="/*/lom:LifeCycle/lom:Contribute/lom:Entity"/>
<xsl:apply-templates select="/*/lom:LifeCycle/lom:Contribute/lom:Date"/>
         <xsl:choose>
           <xsl:when
               test="function-available('external:converter_INFO_to_loncapa_lastrevisiondate')"
             >
             <xsl:value-of select=
        "external:converter_INFO_to_loncapa_lastrevisiondate(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_loncapa_lastrevisiondate()
is not available!
           </xsl:otherwise>
         </xsl:choose>
         <xsl:choose>
           <xsl:when
               test="function-available('external:converter_INFO_to_loncapa_creationdate')"
             >
             <xsl:value-of select=
        "external:converter_INFO_to_loncapa_creationdate(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_loncapa_creationdate()
is not available!
           </xsl:otherwise>
         </xsl:choose>
         <xsl:choose>
           <xsl:when
               test="function-available('external:converter_INFO_to_loncapa_author')"
             >
             <xsl:value-of select=
        "external:converter_INFO_to_loncapa_author(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_loncapa_author()
is not available!
           </xsl:otherwise>
         </xsl:choose>
         <xsl:choose>
           <xsl:when
               test="function-available('external:converter_INFO_to_loncapa_owner')"
             >
             <xsl:value-of select=
        "external:converter_INFO_to_loncapa_owner(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_loncapa_owner()
is not available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:LifeCycle/lom:Contribute/lom:Role">
         <xsl:choose>
           <xsl:when
               test="function-available('external:lomnsdl_LifeCycleContributeRole_to_converter_INFO')"
             >
             <xsl:value-of select=
              "external:lomnsdl_LifeCycleContributeRole_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_LifeCycleContributeRole_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:LifeCycle/lom:Contribute/lom:Entry">
         <xsl:choose>
           <xsl:when
               test="function-available('external:lomnsdl_LifeCycleContributeEntry_to_converter_INFO')"
             >
             <xsl:value-of select=
             "external:lomnsdl_LifeCycleContributeEntry_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_LifeCycleContributeEntry_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:LifeCycle/lom:Contribute/lom:Date">
         <xsl:choose>
           <xsl:when
               test="function-available('external:lomnsdl_LifeCycleContributeDate_to_converter_INFO')"
             >
             <xsl:value-of select=
              "external:lomnsdl_LifeCycleContributeDate_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_LifeCycleContributeDate_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:Technical/lom:Format">
<mime>
         <xsl:choose>
           <xsl:when
  test="function-available('external:lomnsdl_TechnicalFormat_to_loncapa_mime')"
             >
             <xsl:value-of select=
                        "external:lomnsdl_TechnicalFormat_to_loncapa_mime(.)"/>
           </xsl:when>
           <xsl:otherwise>
  Function external:lomnsdl_TechnicalFormat_to_loncapa_mime() is not available!
           </xsl:otherwise>
         </xsl:choose>
</mime>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:Technical/lom:Size">
<bytesize>
         <xsl:choose>
           <xsl:when
test="function-available('external:lomnsdl_TechnicalSize_to_loncapa_bytesize')"
             >
             <xsl:value-of select=
                  "external:lomnsdl_TechnicalSize_to_loncapa_bytesize(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_TechnicalSize_to_loncapa_bytesize() is not available!
           </xsl:otherwise>
         </xsl:choose>
</bytesize>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:Educational/lom:Description">
<notes>
         <xsl:choose>
           <xsl:when
  test="function-available('external:lomnsdl_EducationalDescription_to_loncapa_notes')"
             >
             <xsl:value-of select=
                        "external:lomnsdl_EducationalDescription_to_loncapa_notes(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_EducationalDescription_to_loncapa_notes() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</notes>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="lom:Rights">
         <xsl:choose>
           <xsl:when
               test="function-available('external:lomnsdl_Rights_prepare_converter_INFO')"
             >
             <xsl:value-of select=
        "external:lomnsdl_Rights_prepare_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:lomnsdl_Rights_prepare_converter_INFO() is not available!
           </xsl:otherwise>
         </xsl:choose>
<xsl:apply-templates select="/*/lom:Rights/lom:CopyrightandOtherRestrictions"/>
<xsl:apply-templates select="/*/lom:Rights/lom:Description"/>
         <xsl:choose>
           <xsl:when
               test=
           "function-available('external:converter_INFO_to_loncapa_copyright')"
             >
             <xsl:value-of select=
        "external:converter_INFO_to_loncapa_copyright(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_loncapa_copyright() is not available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:Rights/lom:CopyrightandOtherRestrictions">
         <xsl:choose>
           <xsl:when
            test="function-available('external:lomnsdl_RightsCopyrightandOtherRestrictions_to_converter_INFO')"
             >
             <xsl:value-of select=
  "external:lomnsdl_RightsCopyrightandOtherRestrictions_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function
external:lomnsdl_RightsCopyrightandOtherRestrictions_to_converter_INFO()
is not available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="lom:Rights/lom:Description">
         <xsl:choose>
           <xsl:when
            test="function-available('external:lomnsdl_RightsDescription_to_converter_INFO')"
             >
             <xsl:value-of select=
  "external:lomnsdl_RightsDescription_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:lomnsdl_RightsDescription_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
</xsl:stylesheet>
END

# ------------------------------------------------------ loncapa_to_lomnsdl.xsl
open(OUT,'>loncapa_to_lomnsdl.xsl');
print(OUT <<END);
<?xml version="1.0"?> 
<xsl:stylesheet
  xmlns:loncapa="http://nsdl.lon-capa.org/loncapa/elements/1.1/"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:external="$namespace"
>
<xsl:template match="/">
<!-- These values are stored in memory (converter_INFO) -->
<xsl:apply-templates select="/*/loncapa:language"/>
<xsl:apply-templates select="/*/loncapa:author"/>
<xsl:apply-templates select="/*/loncapa:lastrevisiondate"/>
<xsl:apply-templates select="/*/loncapa:metauri"/>
<xsl:apply-templates select="/*/loncapa:copyright"/>
<xsl:apply-templates select="/*/loncapa:owner"/>
<lom:lom xmlns:lom="http://nsdl.lon-capa.org/lom/elements/6.4/">
<xsl:text>
</xsl:text>
<General>
 <Identifier>
  <Catalog>LON</Catalog>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:converter_INFO_to_lomnsdl_GeneralIdentifierEntry')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_GeneralIdentifierEntry(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:converter_INFO_to_lomnsdl_GeneralIdentifierEntry() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Identifier>
 <xsl:apply-templates select="/*/loncapa:title"/>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:converter_INFO_to_lomnsdl_GeneralLanguage')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_GeneralLanguage(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_GeneralLanguage() is not available!
           </xsl:otherwise>
         </xsl:choose>
 <xsl:apply-templates select="/*/loncapa:abstract"/>
 <xsl:apply-templates select="/*/loncapa:keywords"/>
 <xsl:apply-templates select="/*/loncapa:structure"/>
 <xsl:apply-templates select="/*/loncapa:aggregation"/>
</General>

<LifeCycle>
 <xsl:apply-templates select="/*/loncapa:version"/>
 <Contribute>
 <Role>author</Role>
 <Entity>
         <xsl:choose>
           <xsl:when
                 test=
      "function-available('external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity() is not available!
           </xsl:otherwise>
         </xsl:choose>
 </Entity>
 <Date>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:converter_INFO_to_lomnsdl_LifeCycleContributeDate')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_LifeCycleContributeDate(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_LifeCycleContributeDate() is not available!
           </xsl:otherwise>
         </xsl:choose>
 </Date>
 </Contribute>
</LifeCycle>

<MetaMetadata>
         <xsl:choose>
           <xsl:when
                 test=
        "function-available('external:converter_INFO_to_lomnsdl_MetaMetadata')"
             >
    <xsl:value-of select="external:converter_INFO_to_lomnsdl_MetaMetadata(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_MetaMetadata() is not available!
           </xsl:otherwise>
         </xsl:choose>
</MetaMetadata>

<Technical>
 <xsl:apply-templates select="/*/loncapa:mime"/>
 <xsl:apply-templates select="/*/loncapa:bytesize"/>
 <Location>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:converter_INFO_to_lomnsdl_TechnicalLocation')"
             >
             <xsl:value-of 
             select="external:converter_INFO_to_lomnsdl_TechnicalLocation(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_TechnicalLocation() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Location>
 <Requirement>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_TechnicalRequirement')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_TechnicalRequirement(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_TechnicalRequirement() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Requirement>
</Technical>

<Educational>
 <xsl:apply-templates select="/*/loncapa:notes"/>
 <Language>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_EducationalLanguage')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_EducationalLanguage(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_EducationalLanguage() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Language>
</Educational>

<Rights>
 <CopyrightandOtherRestrictions>yes</CopyrightandOtherRestrictions>
 <Description>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_RightsDescription')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_RightsDescription(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:converter_INFO_to_lomnsdl_RightsDescription() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Description>
</Rights>
<xsl:text>
</xsl:text>

</lom:lom>
</xsl:template>
<xsl:template match="loncapa:title">
<Title>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:loncapa_title_to_lomnsdl_GeneralTitle')"
             >
     <xsl:value-of select="external:loncapa_title_to_lomnsdl_GeneralTitle(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_title_to_lomnsdl_GeneralTitle() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Title>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:abstract">
<Description>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_abstract_to_lomnsdl_GeneralDescription')"
             >
     <xsl:value-of select=
                 "external:loncapa_abstract_to_lomnsdl_GeneralDescription(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_abstract_to_lomnsdl_GeneralDescription() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</Description>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:keywords">
<Keyword>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_keywords_to_lomnsdl_GeneralKeyword')"
             >
     <xsl:value-of select=
                 "external:loncapa_keywords_to_lomnsdl_GeneralKeyword(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_keywords_to_lomnsdl_GeneralKeyword() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</Keyword>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:structure">
<Structure>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_structure_to_lomnsdl_GeneralStructure')"
             >
     <xsl:value-of select=
                  "external:loncapa_structure_to_lomnsdl_GeneralStructure(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_structure_to_lomnsdl_GeneralStructure() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</Structure>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:aggregation">
<AggregationLevel>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel')"
             >
     <xsl:value-of select=
         "external:loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel() is
not available!
           </xsl:otherwise>
         </xsl:choose>
</AggregationLevel>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:version">
<Version>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_version_to_lomnsdl_LifeCycleVersion')"
             >
     <xsl:value-of select=
         "external:loncapa_version_to_lomnsdl_LifeCycleVersion(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:loncapa_version_to_lomnsdl_LifeCycleVersion() is
not available!
           </xsl:otherwise>
         </xsl:choose>
</Version>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:mime">
<Format>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_mime_to_lomnsdl_TechnicalFormat')"
             >
     <xsl:value-of select=
         "external:loncapa_mime_to_lomnsdl_TechnicalFormat(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:loncapa_mime_to_lomnsdl_TechnicalFormat() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Format>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:bytesize">
<Size>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_bytesize_to_lomnsdl_TechnicalSize')"
             >
     <xsl:value-of select=
         "external:loncapa_bytesize_to_lomnsdl_TechnicalSize(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:loncapa_bytesize_to_lomnsdl_TechnicalSize() is
not available!
           </xsl:otherwise>
         </xsl:choose>
</Size>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:notes">
<Description>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_notes_to_lomnsdl_EducationalDescription')"
             >
     <xsl:value-of select=
         "external:loncapa_notes_to_lomnsdl_EducationalDescription(.)"/>
           </xsl:when>
           <xsl:otherwise>
Function external:loncapa_notes_to_lomnsdl_EducationalDescription() is
not available!
           </xsl:otherwise>
         </xsl:choose>
</Description>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:language">
         <xsl:choose>
           <xsl:when
                 test=
          "function-available('external:loncapa_language_to_converter_INFO')"
             >
             <xsl:value-of select=
                           "external:loncapa_language_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
     Function external:loncapa_language_to_converter_INFO() is not available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="loncapa:author">
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:loncapa_author_to_converter_INFO')"
             >
             <xsl:value-of
                    select="external:loncapa_author_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:loncapa_author_to_converter_INFO() is not available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="loncapa:lastrevisiondate">
         <xsl:choose>
           <xsl:when
                 test=
    "function-available('external:loncapa_lastrevisiondate_to_converter_INFO')"
             >
             <xsl:value-of
              select="external:loncapa_lastrevisiondate_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
          Function external:loncapa_lastrevisiondate_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="loncapa:metauri">
         <xsl:choose>
           <xsl:when
                 test=
    "function-available('external:loncapa_metauri_to_converter_INFO')"
             >
             <xsl:value-of
              select="external:loncapa_metauri_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
          Function external:loncapa_metauri_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="loncapa:copyright">
         <xsl:choose>
           <xsl:when
                 test=
    "function-available('external:loncapa_copyright_to_converter_INFO')"
             >
             <xsl:value-of
              select="external:loncapa_copyright_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
          Function external:loncapa_copyright_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
<xsl:template match="loncapa:owner">
         <xsl:choose>
           <xsl:when
                 test=
    "function-available('external:loncapa_owner_to_converter_INFO')"
             >
             <xsl:value-of
              select="external:loncapa_owner_to_converter_INFO(.)"/>
           </xsl:when>
           <xsl:otherwise>
          Function external:loncapa_owner_to_converter_INFO() is not
available!
           </xsl:otherwise>
         </xsl:choose>
</xsl:template>
</xsl:stylesheet>
END

# ----------------------------------------------------- loncapa_to_lomnsdl.xsl2
open(OUT,'>loncapa_to_lomnsdl.xsl2');
print(OUT <<END);
<?xml version="1.0"?> 
<xsl:stylesheet
  xmlns:loncapa="http://nsdl.lon-capa.org/loncapa/elements/1.1/"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:external="$namespace"
>
<xsl:template match="/">
<lom:lom xmlns:lom="http://nsdl.lon-capa.org/lom/elements/6.4/">
<xsl:text>
</xsl:text>
<!-- These values are stored in memory (converter_INFO) -->
<xsl:apply-templates select="/*/loncapa:language"/>
<xsl:apply-templates select="/*/loncapa:author"/>
<xsl:apply-templates select="/*/loncapa:lastrevisiondate"/>
<xsl:apply-templates select="/*/loncapa:metauri"/>
<xsl:apply-templates select="/*/loncapa:copyright"/>
<xsl:apply-templates select="/*/loncapa:owner"/>

<General>
 <Identifier>
  <Catalog>LON</Catalog>
  <Entry><!-- call mem --></Entry>
 </Identifier>
 <xsl:apply-templates select="/*/loncapa:title"/>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:converter_INFO_to_lomnsdl_GeneralLanguage')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_GeneralLanguage(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_GeneralLanguage() is not available!
           </xsl:otherwise>
         </xsl:choose>
 <xsl:apply-templates select="/*/loncapa:abstract"/>
 <xsl:apply-templates select="/*/loncapa:keywords"/>
 <xsl:apply-templates select="/*/loncapa:structure"/>
 <xsl:apply-templates select="/*/loncapa:aggregation"/>
</General>

<LifeCycle>
 <xsl:apply-templates select="/*/loncapa:version"/>
 <Contribute>
 <Role>Creator</Role>
 <Entity>
         <xsl:choose>
           <xsl:when
                 test=
      "function-available('external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_LifeCycleContributeEntity() is not available!
           </xsl:otherwise>
         </xsl:choose>
 </Entity>
 <Date>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:converter_INFO_to_lomnsdl_LifeCycleContributeDate')"
             >
     <xsl:value-of select="external:converter_INFO_to_lomnsdl_LifeCycleContributeDate(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:converter_INFO_to_lomnsdl_LifeCycleContributeDate() is not available!
           </xsl:otherwise>
         </xsl:choose>
 </Date>
 </Contribute>
</LifeCycle>

<MetaMetadata>
         <xsl:choose>
           <xsl:when
                 test=
        "function-available('external:converter_INFO_to_lomnsdl_MetaMetadata')"
             >
    <xsl:value-of select="external:converter_INFO_to_lomnsdl_MetaMetadata(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_MetaMetadata() is not available!
           </xsl:otherwise>
         </xsl:choose>
</MetaMetadata>

<Technical>
 <xsl:apply-templates select="/*/loncapa:mime"/>
 <xsl:apply-templates select="/*/loncapa:bytesize"/>
 <Location>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:converter_INFO_to_lomnsdl_TechnicalLocation')"
             >
             <xsl:value-of 
             select="external:converter_INFO_to_lomnsdl_TechnicalLocation(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_TechnicalLocation() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Location>
 <Requirement>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_TechnicalRequirement')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_TechnicalRequirement(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_TechnicalRequirement() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Requirement>
</Technical>

<Educational>
 <xsl:apply-templates select="/*/loncapa:notes"/>
 <Language>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_EducationalLanguage')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_EducationalLanguage(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:converter_INFO_to_lomnsdl_EducationalLanguage() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Language>
</Educational>

<Rights>
 <CopyrightandOtherRestrictions>yes</CopyrightandOtherRestrictions>
 <Description>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:converter_INFO_to_lomnsdl_RightsDescription')"
             >
             <xsl:value-of 
          select="external:converter_INFO_to_lomnsdl_RightsDescription(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:converter_INFO_to_lomnsdl_RightsDescription() is not
available!
           </xsl:otherwise>
         </xsl:choose>
 </Description>
</Rights>
<xsl:text>
</xsl:text>
</lom:lom>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:title">
<Title>
         <xsl:choose>
           <xsl:when
                 test=
         "function-available('external:loncapa_title_to_lomnsdl_GeneralTitle')"
             >
     <xsl:value-of select="external:loncapa_title_to_lomnsdl_GeneralTitle(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_title_to_lomnsdl_GeneralTitle() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Title>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:abstract">
<Description>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_abstract_to_lomnsdl_GeneralDescription')"
             >
             <xsl:value-of
           select="external:loncapa_abstract_to_lomsdl_GeneralDescription(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:loncapa_abstract_to_lomnsdl_GeneralDescription() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Description>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:keywords">
<Keyword>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_keywords_to_lomnsdl_GeneralKeyword')"
             >
             <xsl:value-of
           select="external:loncapa_keywords_to_lomsdl_GeneralKeyword(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:loncapa_keywords_to_lomnsdl_GeneralKeyword() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Keyword>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:structure">
<Structure>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_structure_to_lomnsdl_GeneralStructure')"
             >
             <xsl:value-of
           select="external:loncapa_structure_to_lomsdl_GeneralStructure(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:loncapa_structure_to_lomnsdl_GeneralStructure() is not
   available!
           </xsl:otherwise>
         </xsl:choose>
</Structure>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:aggregation">
<AggregationLevel>
         <xsl:choose>
           <xsl:when
                 test=
"function-available('external:loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel')"
             >
             <xsl:value-of
           select="external:loncapa_aggregation_to_lomsdl_GeneralAggregationLevel(.)"/>
           </xsl:when>
           <xsl:otherwise>
   Function external:loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel()
   is not available!
           </xsl:otherwise>
         </xsl:choose>
</AggregationLevel>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:version">
<Version>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:loncapa_version_to_lomnsdl_LifeCycleVersion')"
             >
             <xsl:value-of
              select="external:loncapa_version_to_lomsdl_LifeCycleVersion(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:loncapa_version_to_lomnsdl_LifeCycleVersion() is not
        available!
           </xsl:otherwise>
         </xsl:choose>
</Version>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:mime">
<Format>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:loncapa_mime_to_lomnsdl_Format')"
             >
             <xsl:value-of
                    select="external:loncapa_mime_to_lomsdl_Format(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_mime_to_lomnsdl_Format() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Format>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:bytesize">
<Size>
         <xsl:choose>
           <xsl:when
                 test=
   "function-available('external:loncapa_mime_to_lomnsdl_TechnicalSize')"
             >
             <xsl:value-of
                    select="external:loncapa_mime_to_lomsdl_TechnicalSize(.)"/>
           </xsl:when>
           <xsl:otherwise>
    Function external:loncapa_mime_to_lomnsdl_TechnicalSize() is not available!
           </xsl:otherwise>
         </xsl:choose>
</Size>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template match="loncapa:author">
<dc:contributor>
         <xsl:choose>
           <xsl:when
                 test=
          "function-available('external:loncapa_author_to_lomnsdl_contributor')"
             >
             <xsl:value-of
                    select="external:loncapa_author_to_dcnsdl_contributor(.)"/>
           </xsl:when>
           <xsl:otherwise>
     Function external:loncapa_author_to_dcnsdl_contributor() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:contributor>
<xsl:text>
</xsl:text>
<dc:creator>
         <xsl:choose>
           <xsl:when
                 test=
              "function-available('external:loncapa_author_to_dcnsdl_creator')"
             >
             <xsl:value-of
                        select="external:loncapa_author_to_dcnsdl_creator(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:loncapa_author_to_dcnsdl_creator() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:creator>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:owner">
<dc:publisher>
         <xsl:choose>
           <xsl:when
                 test=
             "function-available('external:loncapa_owner_to_dcnsdl_publisher')"
             >
             <xsl:value-of
                       select="external:loncapa_owner_to_dcnsdl_publisher(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:loncapa_owner_to_dcnsdl_publisher() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:publisher>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:subject">
<dc:subject>
         <xsl:choose>
           <xsl:when
                 test=
             "function-available('external:loncapa_subject_to_dcnsdl_subject')"
             >
           <xsl:value-of
                       select="external:loncapa_subject_to_dcnsdl_subject(.)"/>
           </xsl:when>
           <xsl:otherwise>
        Function external:loncapa_subject_to_dcnsdl_subject() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:subject>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:lastrevisiondate">
<dc:date>
         <xsl:choose>
           <xsl:when
                 test=
       "function-available('external:loncapa_lastrevisiondate_to_dcnsdl_date')"
             >
             <xsl:value-of select=
                        "external:loncapa_lastrevisiondate_to_dcnsdl_date(.)"/>
           </xsl:when>
           <xsl:otherwise>
  Function external:loncapa_lastrevisiondate_to_dcnsdl_date() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:date>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:mime">
<dc:type>
         <xsl:choose>
           <xsl:when
                 test=
                   "function-available('external:loncapa_mime_to_dcnsdl_type')"
             >
             <xsl:value-of select="external:loncapa_mime_to_dcnsdl_type(.)"/>
           </xsl:when>
           <xsl:otherwise>
              Function external:loncapa_mime_to_dcnsdl_type() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:type>
<xsl:text>
</xsl:text>
<dc:format>
         <xsl:choose>
           <xsl:when
                 test=
                 "function-available('external:loncapa_mime_to_dcnsdl_format')"
             >
             <xsl:value-of select="external:loncapa_mime_to_dcnsdl_format(.)"/>
           </xsl:when>
           <xsl:otherwise>
            Function external:loncapa_mime_to_dcnsdl_format() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:format>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:uri">
<dc:identifier>
         <xsl:choose>
           <xsl:when
                 test=
              "function-available('external:loncapa_uri_to_dcnsdl_identifier')"
             >
             <xsl:value-of select=
                               "external:loncapa_uri_to_dcnsdl_identifier(.)"/>
           </xsl:when>
           <xsl:otherwise>
         Function external:loncapa_uri_to_dcnsdl_identifier() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:identifier>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:language">
<dc:language>
         <xsl:choose>
           <xsl:when
                 test=
           "function-available('external:loncapa_language_to_dcnsdl_language')"
             >
             <xsl:value-of select=
                            "external:loncapa_language_to_dcnsdl_language(.)"/>
           </xsl:when>
           <xsl:otherwise>
      Function external:loncapa_language_to_dcnsdl_language() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:language>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="loncapa:copyright">
<dc:rights>
         <xsl:choose>
           <xsl:when
                 test=
            "function-available('external:loncapa_copyright_to_dcnsdl_rights')"
             >
             <xsl:value-of select=
                            "external:loncapa_copyright_to_dcnsdl_rights(.)"/>
           </xsl:when>
           <xsl:otherwise>
       Function external:loncapa_copyright_to_dcnsdl_rights() is not available!
           </xsl:otherwise>
         </xsl:choose>
</dc:rights>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
END
close(OUT);

# =================================================== Define external functions

my $func = sub {
    my $text = shift;
    return uc($text);
};

my %ci=(
  'lomnsdl_LifeCycleContributeRole' => '',
  'lomnsdl_LifeCycleContributeEntity' => '',
  'lomnsdl_LifeCycleContributeDate' => '',
  'lomnsdl_LifeCycleContributeAuthor' => '',
  'lomnsdl_LifeCycleContributeLastAuthorDate' => '',
  'lomnsdl_TechnicalLocation' => '',
  'lomnsdl_RightsCopyrightandOtherRestrictions' => '',
  'lomnsdl_RightsDescription' => '',
  'loncapa_uri' => '',
  'loncapa_language' => '',
  'loncapa_author' => '',
  'loncapa_lastrevisiondate' => '',
  'loncapa_metauri' => '',
  'loncapa_copyright' => '',
  'loncapa_owner' => '',
);

my %xslfunctions=(

loncapa_title_to_dcnsdl_title => sub
 { my $text=shift; return $text; },
loncapa_author_to_dcnsdl_contributor => sub
 { my $text=shift; return ''; }, # This is where co-authors should be someday.
loncapa_author_to_dcnsdl_creator => sub
 { my $text=shift; return $text; },
loncapa_owner_to_dcnsdl_publisher => sub
 { my $text=shift; return $text; },
loncapa_subject_to_dcnsdl_subject => sub
 { my $text=shift; return $text; },
loncapa_abstract_to_dcnsdl_description => sub
 { my $text=shift; return $text; },
loncapa_lastrevisiondate_to_dcnsdl_date => sub
 { my $text=shift; return &loncapa_to_rfc_Date($text); },
loncapa_mime_to_dcnsdl_type => sub
 { my $text=shift; return "[unofficial: $text]"; }, # unclear conversion
loncapa_mime_to_dcnsdl_format => sub
 { my $text=shift; return "[unofficial: $text]"; }, # for now, mime suffices
loncapa_uri_to_dcnsdl_identifier => sub
 { my $text=shift; return 'LONCAPA:'.$text; }, # URI or gateway URL here?
loncapa_language_to_dcnsdl_language => sub
 { my $text=shift; return loncapa_to_ISO_language_convert($text); },
loncapa_copyright_to_dcnsdl_rights => sub
 { my $text=shift; return 'LONCAPA:'.$text; },

dcnsdl_title_to_loncapa_title => sub
 { my $text=shift; return $text; },
#dcnsdl_contributor_to_loncapa_author => sub    <--- contributor should go
# { my $text=shift; return "[notdefined: $text]"; },  <--- somewhere someday
dcnsdl_creator_to_loncapa_author => sub
 { my $text=shift; return $text; }, # should maybe have contributor as well?
dcnsdl_publisher_to_loncapa_owner => sub
 { my $text=shift; return $text; }, # assume publisher is owner
dcnsdl_subject_to_loncapa_subject => sub
 { my $text=shift; return $text; }, # DC, however, includes keywords in subject
dcnsdl_description_to_loncapa_abstract => sub
 { my $text=shift; return $text; },
dcnsdl_date_to_loncapa_lastrevisiondate => sub
 { my $text=shift; return &rfc_to_loncapa_Date($text); },
dcnsdl_type_to_loncapa_mime => sub
 { my $text=shift; return "[notdefined: $text]"; },
dcnsdl_format_to_loncapa_mime => sub
 { my $text=shift; return "[notdefined: $text]"; },
dcnsdl_identifier_to_loncapa_uri => sub
 { my $text=shift; return build_gateway_uri_pointer($text); }, # build pointer
dcnsdl_language_to_loncapa_language => sub
 { my $text=shift; return ISO_to_loncapa_language_convert($text); },
dcnsdl_rights_to_loncapa_copyright => sub
 { my $text=shift; return $text; },

lomnsdl_LifeCycleContribute_prepare_converter_INFO => sub
 {
   if ($ci{'lomnsdl_LifeCycleContributeRole'} eq 'author') {
     $ci{'lomnsdl_LifeCycleContributeAuthor'}.=
        $ci{'lomnsdl_LifeCycleContributeEntity'};
     $ci{'lomnsdl_LifeCycleContributeLastAuthorDate'}=
        $ci{'lomnsdl_LifeCycleContributeDate'};
   }
   $ci{'lomnsdl_LifeCycleContributeRole'}='';
   $ci{'lomnsdl_LifeCycleContributeEntity'}='';
   $ci{'lomnsdl_LifeCycleContributeDate'}='';
 },
lomnsdl_GeneralIdentifier_to_loncapa_uri => sub
 { my $text=shift; return build_gateway_uri_pointer($text); }, # build pointer
lomnsdl_GeneralTitle_to_loncapa_title => sub
 { my $text=shift; return $text; },
lomnsdl_GeneralLanguage_to_loncapa_language => sub
 { my $text=shift; return ISO_to_loncapa_language_convert($text); },
lomnsdl_GeneralDescription_to_loncapa_abstract => sub
 { my $text=shift; return $text; },
lomnsdl_GeneralKeyword_to_loncapa_keywords => sub
 { my $text=shift; return $text; },
lomnsdl_GeneralStructure_to_loncapa_structure => sub
 { my $text=shift; return "[unofficial: $text]"; },
lomnsdl_GeneralAggregationLevel_to_loncapa_aggregation => sub
 { my $text=shift; return "[unofficial: $text]"; },
lomnsdl_LifeCycleVersion_to_loncapa_version => sub
 { my $text=shift; return $text; },
lomnsdl_LifeCycleContributeRole_to_converter_INFO => sub
 { my $text=shift; $ci{'LifeCycleContributeRole'}=$text; return ''; },
lomnsdl_LifeCycleContributeEntity_to_converter_INFO => sub
 { my $text=shift; $ci{'LifeCycleContributeEntity'}=$text; return ''; },
lomnsdl_LifeCycleContributeDate_to_converter_INFO => sub
 { my $text=shift; $ci{'LifeCycleContributeDate'}; return ''; },
converter_INFO_to_loncapa_author => sub
 { return $ci{'lomnsdl_LifeCycleContributeAuthor'}; },
converter_INFO_to_loncapa_owner => sub
 { return $ci{'lomnsdl_RightsDescription'}; },
converter_INFO_to_loncapa_lastrevisiondate => sub
 { my $text=shift; return $ci{'lomnsdl_LifeCycleContributeLastAuthorDate'}; },
converter_INFO_to_loncapa_creationdate => sub
 { return ''; },
lomnsdl_MetaMetadataIdentifierCatalog_to_converterINFO => sub
 { my $text=shift; return "[notdefined: $text]"; },
lomnsdl_MetaMetadataIdentifierEntry_to_converterINFO => sub
 { my $text=shift; return "[notdefined: $text]"; },
lomnsdl_TechnicalFormat_to_loncapa_mime => sub
 { my $text=shift; return mimeIANA_to_mimeSuffix($text); },
lomnsdl_TechnicalSize_to_loncapa_bytesize => sub
 { my $text=shift; return $text; },
lomnsdl_Technical_prepare_converter_INFO => sub
 { $ci{'lomnsdl_TechnicalLocation'}=''; },
lomnsdl_TechnicalLocation_to_converter_INFO => sub
 { my $text=shift; return '';}, # need to store techloc with uri in server
lomnsdl_EducationalDescription_to_loncapa_notes => sub
 { my $text=shift; return $text; },
lomnsdl_Rights_prepare_converter_INFO => sub
 { $ci{'RightsCopyrightandOtherRestrictions'}='';
   $ci{'RightsDescription'}='';
 },
lomnsdl_RightsCopyrightandOtherRestrictions_to_converter_INFO => sub
 { my $text=shift; $ci{'RightsCopyrightandOtherRestrictions'}=$text;
   return ''; },
lomnsdl_RightsDescription_to_converter_INFO => sub
 { my $text=shift; $ci{'RightsDescription'}=$text; return ''; },
converter_INFO_to_loncapa_copyright => sub
 { if ($ci{'RightsCopyrightandOtherRestrictions'} eq 'yes') {
     return $ci{'RightsDescription'};
   }
   else {
     return '';
   }
 },
loncapa_uri_to_converter_INFO => sub
 { my $text=shift; $ci{'loncapa_uri'}=$text; return ''; },
converter_INFO_to_lomnsdl_GeneralIdentifier => sub
 { return $ci{'loncapa_uri'}; },
loncapa_title_to_lomnsdl_GeneralTitle => sub
 { my $text=shift; return $text; },
loncapa_language_to_converter_INFO => sub
 { my $text=shift; $ci{'loncapa_language'}=$text; return ''; },
converter_INFO_to_lomnsdl_GeneralLanguage => sub
 { return loncapa_to_ISO_language_convert($ci{'loncapa_language'}); },
loncapa_abstract_to_lomnsdl_GeneralDescription => sub
 { my $text=shift; return $text; },
loncapa_keywords_to_lomnsdl_GeneralKeyword => sub
 { my $text=shift; return $text; },
loncapa_structure_to_lomnsdl_GeneralStructure => sub
 { my $text=shift; return "[unofficial: $text]"; },
loncapa_aggregation_to_lomnsdl_GeneralAggregationLevel => sub
 { my $text=shift; return "[unofficial: $text]"; },
loncapa_version_to_lomnsdl_LifeCycleVersion => sub
 { my $text=shift; return $text; },
loncapa_author_to_converter_INFO => sub
 { my $text=shift; $ci{'loncapa_author'}=$text; return ''; },
loncapa_lastrevisiondate_to_converter_INFO => sub
 { my $text=shift; $ci{'loncapa_lastrevisiondate'}=$text; return ''; },
converter_INFO_to_lomnsdl_LifeCycleContributeEntity => sub
 { return $ci{'loncapa_author'}; },
converter_INFO_to_lomnsdl_LifeCycleContributeDate => sub
 { return $ci{'loncapa_lastrevisiondate'}; },
loncapa_metauri_to_converter_INFO => sub
 { my $text=shift; return "[notdefined: $text]";},
converter_INFO_to_lomnsdl_MetaMetadata => sub
 { my $text=shift; return "[notdefined: $text]"; },
loncapa_mime_to_lomnsdl_TechnicalFormat => sub
 { my $text=shift; return mimeSuffix_to_mimeIANA($text); },
loncapa_bytesize_to_lomnsdl_TechnicalSize => sub
 { my $text=shift; return $text; },
converter_INFO_to_lomnsdl_TechnicalLocation => sub
 { my $text=shift; return "[notdefined: $text]"; },
converter_INFO_to_lomnsdl_TechnicalRequirement => sub
 { my $text=shift; return "[notdefined: $text]"; },
converter_INFO_to_lomnsdl_TechnicalInstallationRemarks => sub
 { my $text=shift; return "[notdefined: $text]"; },
loncapa_notes_to_lomnsdl_EducationalDescription => sub
 { my $text=shift; return $text; },
converter_INFO_to_lomnsdl_EducationalLanguage => sub
 { my $text=shift; return "[notdefined: $text]"; },
loncapa_copyright_to_converter_INFO => sub
 { my $text=shift; return "[notdefined: $text]"; },
loncapa_owner_to_converter_INFO => sub
 { my $text=shift; return "[notdefined: $text]"; },
converter_INFO_to_lomnsdl_RightsDescription => sub
 { my $text=shift; return "[notdefined: $text]"; },

);

foreach my $fname (keys %xslfunctions) {
  $tr->install_function($namespace,$fname,$xslfunctions{$fname});
}

# =================================================== Executing transformations

my $compiled; my $parsed; my $dest_file;

# ---------------------------------- LON-CAPA to NSDL (Dublic Core format)
&query('LON-CAPA to NSDL (Dublic Core format)');
$compiled = $tr->compile_stylesheet_file("loncapa_to_dcnsdl.xsl");
$parsed = $tr->parse_file("tmp_loncapa.xml");
$dest_file="loncapa_to_dcnsdl.xml";
$tr->transform_to_file($parsed, $compiled, $dest_file)
    or die $tr->errstr;

# ---------------------------------- NSDL (Dublic Core format) to LON-CAPA
&query('NSDL (Dublic Core format) to LON-CAPA');
$compiled = $tr->compile_stylesheet_file('dcnsdl_to_loncapa.xsl');
$parsed = $tr->parse_file("tmp_dcnsdl.xml");
$dest_file="dcnsdl_to_loncapa.xml";
$tr->transform_to_file($parsed, $compiled, $dest_file)
    or die $tr->errstr;

# ---------------------------------- LON-CAPA to NSDL (IEEE LOM format)
&query('LON-CAPA to NSDL (IEEE LOM format)');
$compiled = $tr->compile_stylesheet_file("loncapa_to_lomnsdl.xsl");
$parsed = $tr->parse_file("tmp_loncapa.xml");
$dest_file="loncapa_to_lomnsdl.xml";
$tr->transform_to_file($parsed, $compiled, $dest_file)
    or die $tr->errstr;

# ---------------------------------- NSDL (IEEE LOM format) to LON-CAPA
&query('NSDL (IEEE LOM format) to LON-CAPA');
$compiled = $tr->compile_stylesheet_file('lomnsdl_to_loncapa.xsl');
$parsed = $tr->parse_file("tmp_lomnsdl.xml");
$dest_file="lomnsdl_to_loncapa.xml";
$tr->transform_to_file($parsed, $compiled, $dest_file)
    or die $tr->errstr;

# ========================================================= Various subroutines

sub query {
    my ($prompt)=@_;
    print $prompt."\n";
#    my $a=<>;
    return;
}

sub build_gateway_uri_pointer {
    my ($string)=@_;
    return 'longatewayptr://'.$string;
}

sub loncapa_to_rfc_Date {
    my ($val)=@_;
    my $responseDate=Date::Format::time2str("%Y-%m-%dT%T%z",$val);
    $responseDate=~s/(..)$/\:$1/;
    return $responseDate;
}

sub rfc_to_loncapa_Date {
    my ($date)=@_;
    $date=~s/\:(..)$/$1/;
    $time = Date::Parse::str2time($date);
    return $time;
}

sub loncapa_to_ISO_language_convert {
    my ($loncapa_language)=@_;
    my %lhash=(
	       'notset' => '  ', # Not set
	       'notxxx' => '  ', # Not applicable
	       'sariso' => 'AR', # Arabic - ISO
	       'sarwin' => 'AR', # Arabic - Windows
	       'scsiso' => 'CS', # Czech - ISO
	       'scswin' => 'CS', # Czech - Windows
	       'sdaiso' => 'DA', # Danish
	       'sgeiso' => 'DE', # German
	       'sgriso' => 'EL', # Greek - ISO
	       'sgrwin' => 'EL', # Greek - Windows
	       'seniso' => 'EN', # English
	       'sspiso' => 'ES', # Spanish
	       'setiso' => 'ET', # Estonian - ISO
	       'setwin' => 'ET', # Estonian - Windows
	       'sfiiso' => 'FI', # Finnish
	       'sfriso' => 'FR', # French
	       'scriso' => 'HR', # Croatian - ISO
	       'scrwin' => 'HR', # Croatian - Windows
	       'shuiso' => 'HU', # Hungarian - ISO
	       'shuwin' => 'HU', # Hungarian - Windows
	       'sisiso' => 'IS', # Icelandic
	       'sitiso' => 'IT', # Italian
	       'shebiso' => 'HE', # Hebrew - ISO
	       'shebwin' => 'HE', # Hebrew - Windows
	       'sjasjis' => 'JA', # Japanese - SJIS
	       'sjaeuc' => 'JA', # Japanese - EUC
	       'skoeuc' => 'KO', # Korean
	       'sltiso' => 'LT', # Lithuanian - ISO
	       'sltwin' => 'LT', # Lithuanian - Windows
	       'slviso' => 'LV', # Latvian - ISO
	       'slvwin' => 'LV', # Latvian - Windows
	       'sduiso' => 'NL', # Dutch
	       'snoiso' => 'NO', # Norwegian
	       'spliso' => 'PL', # Polish - ISO
	       'splwin' => 'PL', # Polish - Windows
	       'sptiso' => 'PT', # Portuguese
	       'sroiso' => 'RO', # Romanian - ISO
	       'srowin' => 'RO', # Romanian - Windows
	       'sruiso' => 'RU', # Russian - ISO
	       'sruwin' => 'RU', # Russian - Windows
	       'srukoi' => 'RU', # Russian - KOI
	       'sskiso' => 'SK', # Slovak - ISO
	       'sskwin' => 'SK', # Slovak - Windows
	       'ssliso' => 'SL', # Slovenian - ISO
	       'sslwin' => 'SL', # Slovenian - Windows
	       'ssviso' => 'SV', # Swedish
	       'striso' => 'TR', # Turkish - ISO
	       'strwin' => 'TR', # Turkish - Windows
	       'schbig5' => 'ZH', # Chinese - BIG5
	       'scheuc' => 'ZH', Chinese - GB
	       );
    my $iso_language=$lhash{$loncapa_language};
    return $iso_language;
}

sub mimeIANA_to_mimeSuffix {
    my ($text)=@_;
    return "[unofficial: $text]";
}

sub mimeSuffix_to_mimeIANA {
    my ($text)=@_;
    return "[unofficial: $text]";
}

sub ISO_to_loncapa_language_convert {
    my ($iso_language)=@_;
    my %lhash=(
	       '  ' => 'notset', # Not set
	       'AR' => 'sariso', # Arabic - ISO
	       'CS' => 'scsiso', # Czech - ISO
	       'DA' => 'sdaiso', # Danish
	       'DE' => 'sgeiso', # German
	       'EL' => 'sgriso', # Greek - ISO
	       'EN' => 'seniso', # English
	       'ES' => 'sspiso', # Spanish
	       'ET' => 'setiso', # Estonian - ISO
	       'FI' => 'sfiiso', # Finnish
	       'FR' => 'sfriso', # French
	       'HR' => 'scriso', # Croatian - ISO
	       'HU' => 'shuiso', # Hungarian - ISO
	       'IS' => 'sisiso', # Icelandic
	       'IT' => 'sitiso', # Italian
	       'HE' => 'shebiso', # Hebrew - ISO
	       'JA' => 'sjasjis', # Japanese - SJIS
	       'KO' => 'skoeuc', # Korean
	       'LT' => 'sltiso', # Lithuanian - ISO
	       'LV' => 'slviso', # Latvian - ISO
	       'NL' => 'sduiso', # Dutch
	       'NO' => 'snoiso', # Norwegian
	       'PL' => 'spliso', # Polish - ISO
	       'PT' => 'sptiso', # Portuguese
	       'RO' => 'sroiso', # Romanian - ISO
	       'RU' => 'sruiso', # Russian - ISO
	       'RU' => 'srukoi', # Russian - KOI
	       'SK' => 'sskiso', # Slovak - ISO
	       'SL' => 'ssliso', # Slovenian - ISO
	       'SV' => 'ssviso', # Swedish
	       'TR' => 'striso', # Turkish - ISO
	       'ZH' => 'schbig5', # Chinese - BIG5
	       );
    my $loncapa_language=$lhash{uc($iso_language)};
    if (!length($loncapa_language)) {$loncapa_language='notset';}
    return $loncapa_language;
}

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at 
 root@localhost to inform them of the time this error occurred,
 and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
