Viewing file: SchematronStylesheet.py (9.25 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Server/Common/SchematronStylesheet.py,v 1.8 2004/08/30 22:52:17 mbrown Exp $ """ Schematron stylesheet preprocessing
Copyright 2004 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
import cPickle
from Ft.Server import FTSS_URI_SCHEME from Ft.Server.Server.Drivers import FtssInputSource from Ft.Xml import Domlette, InputSource from Ft.Xml.Xslt import Processor, DomWriter, StylesheetReader
STYLESHEET="""<?xml version="1.0" ?> <!-- Preprocessor for the Schematron XML Schema Language. http://www.ascc.net/xml/resource/schematron/schematron.html Copyright (C) 1999 Rick Jelliffe and Academia Sinica Computing Centre Permission to use granted under GPL or MPL. -->
<!-- Schematron basic -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" xmlns:sch="http://www.ascc.net/xml/schematron">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:output method="xml" omit-xml-declaration="no" standalone="yes" indent="yes" />
<xsl:template name="process-prolog"> <axsl:output method="text" /> </xsl:template>
<xsl:template name="process-root"> <xsl:param name="title" /> <xsl:param name="contents" /> <xsl:value-of select="$title" /> <xsl:text> </xsl:text> <xsl:copy-of select="$contents" /> </xsl:template>
<!-- use default rule for process-pattern: ignore name and see --> <!-- use default rule for process-name: output name --> <!-- use default rule for process-assert and process-report: call process-message -->
<xsl:template name="process-message"> <xsl:param name="pattern" /> <xsl:param name="role" /> <xsl:text>In pattern </xsl:text> <xsl:value-of select="$pattern" /> <xsl:if test="$role"> <xsl:text> (</xsl:text> <xsl:value-of select="$role" /> <xsl:text>)</xsl:text> </xsl:if>: <xsl:apply-templates mode="text" /> <xsl:text> </xsl:text> </xsl:template>
<!-- Skeleton: namespace enabled version -->
<xsl:template match="sch:schema"> <axsl:stylesheet version="1.0"> <xsl:for-each select="sch:ns"> <xsl:attribute name="{concat(@prefix, ':dummy-for-xmlns')}" namespace="{@uri}"/> </xsl:for-each> <xsl:call-template name="process-prolog"/> <xsl:apply-templates mode="do-keys" /> <axsl:template match='/'> <xsl:call-template name="process-root"> <xsl:with-param name="fpi" select="@fpi" /> <xsl:with-param name="title" select="sch:title" /> <xsl:with-param name="contents"> <xsl:apply-templates mode="do-all-patterns" /> </xsl:with-param> </xsl:call-template> </axsl:template> <xsl:apply-templates /> <axsl:template match="text()" priority="-1"> <!-- strip characters --> </axsl:template> </axsl:stylesheet> </xsl:template>
<xsl:template match="sch:pattern" mode="do-all-patterns" > <xsl:call-template name="process-pattern"> <xsl:with-param name="name" select="@name" /> <xsl:with-param name="id" select="@id" /> <xsl:with-param name="see" select="@see" /> <xsl:with-param name="fpi" select="@fpi" /> </xsl:call-template> <axsl:apply-templates mode='M{count(preceding-sibling::*)}' /> </xsl:template>
<xsl:template match="sch:pattern"> <xsl:apply-templates /> <axsl:template match="text()" priority="-1" mode="M{count(preceding-sibling::*)}"> <!-- strip characters --> </axsl:template> </xsl:template>
<xsl:template match="sch:rule"> <axsl:template match='{@context}' priority='{4000 - count(preceding-sibling::*)}' mode='M{count(../preceding-sibling::*)}'> <xsl:apply-templates /> <axsl:apply-templates mode='M{count(../preceding-sibling::*)}'/> </axsl:template> </xsl:template>
<xsl:template match="sch:name" mode="text"> <axsl:text xml:space="preserve"> </axsl:text> <xsl:choose> <xsl:when test='@path' > <xsl:call-template name="process-name"> <xsl:with-param name="name" select="'name({@path})'" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="process-name"> <xsl:with-param name="name" select="'name(.)'" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> <axsl:text xml:space="preserve"> </axsl:text> </xsl:template>
<xsl:template match="sch:assert"> <axsl:choose> <axsl:when test='{@test}'/> <axsl:otherwise> <xsl:call-template name="process-assert"> <xsl:with-param name="pattern" select="ancestor::sch:pattern/@name" /> <xsl:with-param name="role" select="@role" /> </xsl:call-template> </axsl:otherwise> </axsl:choose> </xsl:template>
<xsl:template match="sch:report"> <axsl:if test='{@test}'> <xsl:call-template name="process-report"> <xsl:with-param name="pattern" select="ancestor::sch:pattern/@name" /> <xsl:with-param name="role" select="@role" /> </xsl:call-template> </axsl:if> </xsl:template>
<xsl:template match="sch:rule/sch:key" mode="do-keys"> <axsl:key match="{../@context}" name="{@name}" use="{@path}" /> </xsl:template>
<xsl:template match="text()" priority="-1" mode="do-keys" > <!-- strip characters --> </xsl:template>
<xsl:template match="text()" priority="-1" mode="do-all-patterns"> <!-- strip characters --> </xsl:template>
<xsl:template match="text()" priority="-1"> <!-- strip characters --> </xsl:template>
<xsl:template match="text()" mode="text"> <xsl:value-of select="normalize-space(.)" /> </xsl:template>
<!-- ============================================================== -->
<!-- report schema errors -->
<xsl:template match="sch:title|sch:ns|sch:key"> <xsl:if test="count(*)"> <xsl:message> <xsl:text>Warning: </xsl:text> <xsl:value-of select="name(.)" /> <xsl:text> must not contain any child elements</xsl:text> </xsl:message> </xsl:if> </xsl:template>
<xsl:template match="*"> <xsl:message> <xsl:text>Warning: unrecognized element </xsl:text> <xsl:value-of select="name(.)" /> </xsl:message> </xsl:template>
<xsl:template match="*" mode="text"> <xsl:message> <xsl:text>Warning: unrecognized element </xsl:text> <xsl:value-of select="name(.)" /> </xsl:message> </xsl:template>
<!-- ============================================================== -->
<!-- Default templates -->
<!--<xsl:template name="process-prolog" />--> <!-- no params -->
<!--<xsl:template name="process-root"> <xsl:param name="contents" /> <xsl:copy-of select="$contents" />--> <!-- additional params: fpi, title --> <!--</xsl:template>-->
<xsl:template name="process-pattern" /> <!-- params: name, id, see, fpi -->
<xsl:template name="process-name"> <xsl:param name="name" /> <axsl:value-of select="{$name}" /> </xsl:template>
<xsl:template name="process-assert"> <xsl:param name="pattern" /> <xsl:param name="role" /> <xsl:call-template name="process-message"> <xsl:with-param name="pattern" select="$pattern" /> <xsl:with-param name="role" select="$role" /> </xsl:call-template> </xsl:template>
<xsl:template name="process-report"> <xsl:param name="pattern" /> <xsl:param name="role" /> <xsl:call-template name="process-message"> <xsl:with-param name="pattern" select="$pattern" /> <xsl:with-param name="role" select="$role" /> </xsl:call-template> </xsl:template>
<!--<xsl:template name="process-message">--> <!-- params: pattern, role --> <!-- <xsl:apply-templates mode="text" /> </xsl:template>-->
</xsl:stylesheet>"""
_STYLESHEET_INSTANCE = None
def Init(): #Create the cpickled version of the schematron transformation global _STYLESHEET_INSTANCE r = StylesheetReader.StylesheetReader() isrc = InputSource.DefaultFactory.fromString(STYLESHEET, FTSS_URI_SCHEME + ':///schematron-stylesheet.xslt') doc = r.fromSrc(isrc) _STYLESHEET_INSTANCE = cPickle.dumps(doc.root) return
def GetSchematronInstance(): if _STYLESHEET_INSTANCE is None: Init() return _STYLESHEET_INSTANCE
def ParseSchematron(src, uri, driver, external=0): #Create a processor to create the meta sheet p = Processor.Processor()
#Instantiate the schematron stylesheet schSt = cPickle.loads(GetSchematronInstance()).stylesheet p.appendStylesheetInstance(schSt) writer = DomWriter.DomWriter()
#Create the meta stylesheet if external: isrc = InputSource.DefaultFactory.fromString(src, uri) else: isrc = FtssInputSource.FtssInputSourceFactory.fromString(src, uri, driver) p.run(isrc, writer=writer)
doc = writer.getResult() reader = StylesheetReader.StylesheetReader() schema = reader.fromDocument(doc, uri)
# Remove node cache for document('') to allow for pickling. # The resulting stylesheet doesn't use document('') anyway. del schema.root.sourceNodes[uri]
return schema
|