ivelin 02/04/03 22:21:51
Added: src/scratchpad/src/org/apache/cocoon/validation/schematron
ActivePattern.java Assert.java Pattern.java
Phase.java Report.java Rule.java SchemaBuilder.java
SchematronSchema.java ValidationResult.java
Validator.java ZSchematronTest.java
src/scratchpad/src/org/apache/cocoon/xmlform
FormBeanBinder.java
src/scratchpad/webapp/mount/xmlform README.txt
formbean2html-Demo2.xsl formbean2html.xsl
insertFormBean-Demo2.xml insertFormBean.xml
sitemap.xmap success-page-Demo2.html
src/scratchpad/webapp/mount/xmlform/castor-mappings
test-mapping.xml
src/scratchpad/webapp/mount/xmlform/schematron
schematron1-5.xsd some-xmlform.xml
xmlform-extensions.xsl xmlform-sch-report-Demo2.xml
xmlform-sch-report.xml xmlform-sch-report.xsl
xmlform-schematron.xsl xmlform-wrappers.xsl
xmlform.bat xslt.bat
Log:
Added CocoonForm demos. HTML Form <-> JavaBean binding through XPath and
Schematron validation.
Revision Changes Path
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ActivePattern.java
Index: ActivePattern.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ActivePattern.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron phase
* <active pattern="some"> element
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class ActivePattern
{
private String pattern_;
/**
* Returns the active pattern name
*/
public String getPattern()
{
return pattern_;
}
/**
* Sets the active pattern name
*/
public void setPattern( String pattern )
{
pattern_ = pattern;
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Assert.java
Index: Assert.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Assert.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
/**
* Represents a Schematron assert element
*
* example:
* <assert test="count(ear)=2">A <name/> element should contain two
<emph>ear</emph> elements.</assert>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Assert
{
private String test_;
private String message_;
private String diagnostics_;
/**
* Returns the test attribute
*/
public String getTest()
{
return test_;
}
/**
* Sets the test attribute
*/
public void setTest( String newTest )
{
test_ = newTest;
}
/**
* Returns the message for to the element
*/
public String getMessage()
{
return message_;
}
/**
* Sets the message for to the element
*/
public void setMessage( String newMessage )
{
message_ = newMessage;
}
/**
* Returns the diagnostics list
*/
public String getDiagnostics()
{
return diagnostics_;
}
/**
* Sets the diagnostics list
*/
public void setDiagnostics( String newDiagnostics )
{
diagnostics_ = newDiagnostics;
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Pattern.java
Index: Pattern.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Pattern.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron pattern
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Pattern
{
private String name_;
private String id_;
private ArrayList rules_ = new ArrayList ();
/**
* Returns the id of the pattern
*/
public String getId()
{
return id_;
}
/**
* Sets the id of the pattern
*/
public void setId( String newId )
{
id_ = newId;
}
/**
* Returns the name of the pattern
*/
public String getName()
{
return name_;
}
/**
* Sets the name of the pattern
*/
public void setName( String newName )
{
name_ = newName;
}
/**
* Returns the list of rules
*/
public List getRule()
{
return rules_;
}
/**
* Sets the list of rules
*/
public void setRule(Collection newRules)
{
rules_ = new ArrayList();
rules_.addAll ( newRules );
}
/**
* Add a rule to the list
*/
public void addRule(Rule r)
{
rules_.add ( r );
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Phase.java
Index: Phase.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Phase.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron phase element
*
* Example:
* <phase id="basicValidation">
* <active pattern="text" />
* <active pattern="tables" />
* <active pattern="attributePresence" />
* </phase>
*
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Phase
{
private String id_;
private ArrayList active_ = new ArrayList ();
/**
* Returns the id of the phase
*/
public String getId()
{
return id_;
}
/**
* Sets the id of the phase
*/
public void setId( String newId )
{
id_ = newId;
}
/**
* Returns the list of active patterns
*/
public List getActive()
{
return active_;
}
/**
* Sets the list of active patterns
*/
public void setActive(Collection newActivePatterns)
{
active_ = new ArrayList();
active_.addAll ( newActivePatterns );
}
/**
* Add a pattern to the list of active patterns
*/
public void addActive(ActivePattern p)
{
active_.add ( p );
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Report.java
Index: Report.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Report.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
/**
* Represents a Schematron report element
*
* <report test="when">message</report>
* is equivalent to
* <assert test="not(when)">message</assert>
*
* example:
* <report test="bone">This dog has a bone.</report>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Report extends Assert
{
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Rule.java
Index: Rule.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Rule.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
/**
* Represents a Schematron rule element
*
* From the Schematron specification:
*
* example:
* <rule context="dog">
* <assert test="count(ear) = 2">A 'dog' element should contain two 'ear'
elements.</assert>
* <report test="bone">This dog has a bone.</report>
* </rule>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Rule
{
private String context_;
private ArrayList asserts_ = new ArrayList ();
private ArrayList reports_ = new ArrayList ();
/**
* Returns the context of the pattern
*/
public String getContext()
{
return context_;
}
/**
* Sets the context of the pattern
*/
public void setContext( String newContext )
{
context_ = newContext;
}
/**
* Returns the list of the assertion rules
*/
public List getAssert()
{
return asserts_;
}
/**
* Sets the the list of the assertion rules
*/
public void setAssert(Collection newAsserts)
{
asserts_ = new ArrayList();
asserts_.addAll ( newAsserts );
}
/**
* Add an assert rule
*/
public void addAssert(Assert a)
{
asserts_.add ( a );
}
/**
* Returns the list of the report rules
*/
public List getReport()
{
return reports_;
}
/**
* Sets the list of the report rules
*/
public void setReport(Collection newReports)
{
reports_ = new ArrayList();
reports_.addAll ( newReports );
}
/**
* Add a report rule
*/
public void addReport(Report r)
{
reports_.add ( r );
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchemaBuilder.java
Index: SchemaBuilder.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchemaBuilder.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.io.OutputStreamWriter;
import java.io.InputStream;
// java classes
import java.util.Properties;
import java.util.List;
import java.io.IOException;
import java.net.URL;
// XML classes
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
// logger
import org.apache.log.Hierarchy;
import org.apache.log.Logger;
import org.apache.log.Priority;
// JXPath classes
import org.apache.commons.jxpath.JXPathContext;
/**
* A helper class which builds a SchematronSchema instance object
* from a DOM source
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class SchemaBuilder
{
/**
* the schema name space prefix used in the schema document
*/
private String schemaPrefix_;
/**
* the default schema name space prefix
*/
private String defaultSchemaPrefix_ = "sch";
/*
* private logger
*/
private Logger logger = setupLogger();
//
// Constructors
//
/**
* initialize logger
*/
protected Logger setupLogger()
{
Logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor("XmlForm");
logger.setPriority( Priority.ERROR );
return logger;
}
/**
* Builds a new Schema instance from
* the given XML InputSource
*
* @param schemaSrc
* the Schema document XML InputSource
*/
public SchematronSchema build( InputSource schemaSrc )
{
SchematronSchema schema = null;
try {
// load Schema file into a DOM document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
DocumentBuilder dbld = dbf.newDocumentBuilder ();
Document document = dbld.parse( schemaSrc );
schema = buildSchema( document );
} catch (Exception e) {
logger.error("!!! Failed loading Schematron schema", e);
throw new RuntimeException(" !!! Failed loading Schematron schema:
\n" + e);
}
return schema;
} // build
/**
* Build Schematron schema object from a DOM document
* @ param doc DOM document containing the schema
*
*/
protected SchematronSchema buildSchema( Document doc )
{
SchematronSchema schema = new SchematronSchema();
boolean errors = false;
doc.getNamespaceURI ();
doc.getPrefix ();
// Initialize the JXPath context
Element root = doc.createElement ( "root" );
Element schemaElement = doc.getDocumentElement ();
schemaPrefix_ = schemaElement.getPrefix ();
root.appendChild ( schemaElement );
JXPathContext jxpContext = JXPathContext.newContext ( root );
jxpContext.setLenient(false);
// Bind sch:schema element
// schema title
String title = (String) jxpContext.getValue ( "/schema/title",
String.class );
schema.setTitle( title );
logger.debug( "Schema title: " + schema.getTitle());
bindPatterns( schema, jxpContext );
bindPhases( schema, jxpContext );
return schema;
}
/**
* populates the patterns elements from the dom tree
*
* @param schema the schema instance
* @param jxpContext
*/
protected void bindPatterns( SchematronSchema schema, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema patterns
int ptCount = ((Integer) jxpContext.getValue ( "count(/schema/pattern)",
Integer.class )).intValue();
logger.debug( "\nNumber of patterns: " + ptCount);
for (int i = 1; i <= ptCount; i++)
{
logger.debug( "Pattern# : " + i);
Pattern pattern = new Pattern();
String ptprefix = "/schema/pattern[" + i + "]";
String name = (String) jxpContext.getValue ( ptprefix + "/@name",
String.class );
pattern.setName( name );
logger.debug( "Pattern name : " + pattern.getName());
String id = (String) jxpContext.getValue ( ptprefix + "/@id",
String.class );
pattern.setId( id );
logger.debug( "Pattern id : " + pattern.getId() );
bindRules( pattern, ptprefix, jxpContext );
schema.addPattern( pattern );
}
}
/**
* populates the rules elements for a pattern
* from the dom tree
*
* @param pattern
* @param pathPrefix pattern path prefix
* @param jxpContext JXPathContext
*/
protected void bindRules( Pattern pattern, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema rules
int ruleCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix +
"/rule)", Integer.class )).intValue();
logger.debug( "\nNumber of rules: " + ruleCount);
for (int i = 1; i <= ruleCount; i++)
{
logger.debug( "Rule# : " + i);
Rule rule = new Rule();
String rulePrefix = pathPrefix + "/rule[" + i + "]";
String context = (String) jxpContext.getValue ( rulePrefix +
"/@context", String.class );
rule.setContext( context );
logger.debug( "Rule context : " + rule.getContext());
bindAsserts( rule, rulePrefix, jxpContext );
pattern.addRule( rule );
}
}
/**
* populates the assert elements for a rule
* from the dom tree
*
* @param rule
* @param pathPrefix rule path prefix
* @param jxpContext JXPathContext
*/
protected void bindAsserts( Rule rule, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema reports
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/assert)", Integer.class )).intValue();
logger.debug( "\nNumber of asserts: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "Assert# : " + i);
Assert assert = new Assert();
String assertPrefix = pathPrefix + "/assert[" + i + "]";
String test = (String) jxpContext.getValue ( assertPrefix + "/@test",
String.class );
assert.setTest( test );
logger.debug( "Assert test : " + assert.getTest());
// since diagnostics is a non-mandatory element
// we will try to get its value in a lenient mode
jxpContext.setLenient(true);
String diagnostics = (String) jxpContext.getValue ( assertPrefix +
"/@diagnostics", String.class );
assert.setDiagnostics( diagnostics );
logger.debug( "Assert diagnostics : " + assert.getDiagnostics());
jxpContext.setLenient(false);
String message = (String) jxpContext.getValue ( assertPrefix,
String.class );
assert.setMessage( message );
logger.debug( "Assert message : " + assert.getMessage());
rule.addAssert( assert );
}
}
/**
* populates the assert elements for a rule
* from the dom tree
*
* @param rule
* @param pathPrefix rule path prefix
* @param jxpContext JXPathContext
*/
protected void bindRerports( Rule rule, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema reports
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/report)", Integer.class )).intValue();
logger.debug( "\nNumber of reports: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "Report# : " + i);
Report report = new Report();
String assertPrefix = pathPrefix + "/report[" + i + "]";
String test = (String) jxpContext.getValue ( assertPrefix + "/@test",
String.class );
report.setTest( test );
logger.debug( "Report test : " + report.getTest());
// since diagnostics is a non-mandatory element
// we will try to get its value in a lenient mode
jxpContext.setLenient(true);
String diagnostics = (String) jxpContext.getValue ( assertPrefix +
"/@diagnostics", String.class );
report.setDiagnostics( diagnostics );
logger.debug( "Report diagnostics : " + report.getDiagnostics());
jxpContext.setLenient(false);
String message = (String) jxpContext.getValue ( assertPrefix,
String.class );
report.setMessage( message );
logger.debug( "Report message : " + report.getMessage());
rule.addReport( report );
}
}
/**
* populates the phases elements from the dom tree
*
* @param schema the schema instance
* @param jxpContext
*/
protected void bindPhases( SchematronSchema schema, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema phases
int phaseCount = ((Integer) jxpContext.getValue ( "count(/schema/phase)",
Integer.class )).intValue();
logger.debug( "\nNumber of phases: " + phaseCount);
for (int i = 1; i <= phaseCount; i++)
{
logger.debug( "phase# : " + i);
Phase phase = new Phase();
String phprefix = "/schema/phase[" + i + "]";
String id = (String) jxpContext.getValue ( phprefix + "/@id",
String.class );
phase.setId( id );
logger.debug( "phase id : " + phase.getId());
bindPhaseActivePatterns( phase, phprefix, jxpContext );
schema.addPhase( phase );
}
}
protected void bindPhaseActivePatterns( Phase phase, String pathPrefix,
JXPathContext jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// phase active patterns
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/active)", Integer.class )).intValue();
logger.debug( "Number of active patterns: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "active pattern # : " + i);
ActivePattern activePattern = new ActivePattern();
String assertPrefix = pathPrefix + "/active[" + i + "]";
String pt = (String) jxpContext.getValue ( assertPrefix + "/@pattern",
String.class );
activePattern.setPattern( pt );
logger.debug( "Phase active pattern : " + activePattern.getPattern());
phase.addActive( activePattern );
}
}
/*
* Replace all occurances of sch: with the actual Schema prefix used in the
document
*
* @todo fix this implementaion. There are problems with DOM.
* Returns null instead of the actual namespace prefix (e.g. "sch") as
expected.
*/
protected String fixns( String path )
{
// Ironicly, at the time I am writing this
// JDK 1.4 is offering String.replaceAll(regex, str)
// I don't use it however for backward compatibility
StringBuffer strbuf = new StringBuffer( path );
int i = 0;
int j = 0;
String dprefix = defaultSchemaPrefix_ + ":";
int dplen = dprefix.length();
while ( ( j = path.indexOf ( dprefix, i ) ) >= 0 )
{
strbuf.append ( path.substring ( i, j ) );
strbuf.append ( schemaPrefix_ );
strbuf.append ( ':' );
i = j + dplen;
}
strbuf.append( path.substring ( i ) );
return strbuf.toString ();
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java
Index: SchematronSchema.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
/**
* Represents a Schematron Schema
*
* Specification:
* http://www.ascc.net/xml/resource/schematron/Schematron2000.html
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class SchematronSchema
{
private String title_;
private ArrayList patterns_ = new ArrayList();
private ArrayList phases_ = new ArrayList();
/**
* Returns the message for to the element
*/
public String getTitle()
{
return title_;
}
/**
* Sets the message for to the element
*/
public void setTitle( String newTitle )
{
title_ = newTitle;
}
/**
* Returns a list of the patterns which
* contain messages that failed during validation
*/
public List getPattern()
{
return patterns_;
}
/**
* Sets the list of the patterns which
* contain messages that failed during validation
*/
public void setPattern(Collection newPatterns)
{
patterns_ = new ArrayList();
patterns_.addAll ( newPatterns );
}
/**
* Add a pattern to the list
*/
public void addPattern(Pattern p)
{
patterns_.add ( p );
}
/**
* Returns the list of schema phases
*/
public List getPhase()
{
return phases_;
}
/**
* Sets the list of schema phases
*/
public void setPhase(Collection newPhases)
{
phases_ = new ArrayList();
phases_.addAll ( newPhases );
}
/**
* Add a pattern to the list
*/
public void addPhase(Phase p)
{
phases_.add ( p );
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java
Index: ValidationResult.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents the result of a Schematron validation process
*
* <validationResult>
* list of <pattern> elements with <rule> subelements
* </validationResult>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class ValidationResult
{
private ArrayList patterns_ = new ArrayList();
/**
* Returns a list of the patterns which
* contain rules that failed during validation
*/
public List getPattern()
{
return patterns_;
}
/**
* Sets the list of the patterns which
* contain rules that failed during validation
*/
public void setPattern(Collection newPatterns)
{
patterns_ = new ArrayList();
patterns_.addAll ( newPatterns );
}
/**
* Add a pattern to the list
*/
public void addPattern(Pattern p)
{
patterns_.add ( p );
}
public boolean isEmpty ()
{
return patterns_.isEmpty ();
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Validator.java
Index: Validator.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/Validator.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.validation.schematron;
import java.io.OutputStreamWriter;
import java.io.InputStream;
// java classes
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.io.IOException;
import java.net.URL;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.File;
// XML classes
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
// logger
import org.apache.log.Hierarchy;
import org.apache.log.Logger;
import org.apache.log.Priority;
// JXPath classes
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
/**
* An object representing a single Schematron schema, used to validate
* multiple XML instances.
*
* This implementation can validate JavaBeans and DOM documents.
* It is based exclusively on the JXPath library from the Jakarta Commons
project.
* See http://jakarta.apache.org/commons/
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Validator
{
/** The schema instance for this Validator
* It is initialized once when a new Validator instance
* is created and used multiple times for validating
* different JavaBeans/DOM objects against the schema
*/
private SchematronSchema schema_;
/**
* lookup map, with phase id keys.
* Used for efficiency when validating by phase
*/
private Map phaseMap_ = new HashMap();
/**
* the schema name space prefix used in the schema document
*/
private String schemaPrefix_;
/**
* the default schema name space prefix
*/
private String defaultSchemaPrefix_ = "sch";
/*
* private logger
*/
private Logger logger = setupLogger();
//
// Constructors
//
/**
* Constructs a new Validator object
* for a given Schematron schema source.
*
* @param schema
* The Schematron schema source
*/
public Validator ( InputSource schemaSrc )
{
init( schemaSrc );
preparePhaseMap();
}
/**
* Constructs a new Validator object for a given Schematron schema.
*
* @param schema
* The Schematron schema
*/
public Validator (SchematronSchema schema)
{
schema_ = schema;
preparePhaseMap();
}
//
// helper methods for the constructors
//
/**
* initialize logger
*/
protected Logger setupLogger()
{
Logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor("XmlForm");
logger.setPriority( Priority.ERROR );
return logger;
}
/**
* Initializes a new Validator object from the given Schematron
* schema
*
* @param schema
* The Schematron schema
* @param params
* Global parameters for the preprocessor.
*/
protected void init( InputSource schemaSrc )
{
SchemaBuilder schBuilder = new SchemaBuilder();
schema_ = schBuilder.build ( schemaSrc );
} // init
protected void preparePhaseMap()
{
Map patternMap = new HashMap();
Iterator ptiter = schema_.getPattern().iterator();
while (ptiter.hasNext())
{
Pattern pattern = (Pattern) ptiter.next();
patternMap.put( pattern.getId(), pattern );
}
Iterator phiter = schema_.getPhase().iterator();
while (phiter.hasNext())
{
Phase phase = (Phase) phiter.next();
List activePatterns = new ArrayList();
phaseMap_.put( phase.getId(), activePatterns );
Iterator activeIter = phase.getActive().iterator();
while (activeIter.hasNext())
{
ActivePattern active = (ActivePattern) activeIter.next();
activePatterns.add( patternMap.get( active.getPattern() ) );
}
}
}
//
// public methods
//
/**
* Performs validation of the passed JavaBean or DOM object.
*
* This method tries to match all pattern, since phase is not supplied
*
* @param jbean The JavaBean or DOM object to be validated.
* @return A Result object which represents the result
* of the validation.
*/
public ValidationResult validate(Object jbean)
{
return validate ( jbean, new Properties() );
}
/**
* Performs validation of the passed JavaBean or DOM object.
*
* This method tries to find the "phase" attribute
* and runs the active patterns for the phase.
* If phase not found, the method will try to match all patterns
*
*
* @param jbean The JavaBean or DOM object to be validated.
* @param props Properties which control different aspects of the
* validation process. This method only looks for the phase property.
* Another implementation may use other.
*
* @return A Result object which represents the result
* of the validation.
*/
public ValidationResult validate(Object jbean, Properties props)
{
String phase = (String) props.get("phase");
List patterns = null;
if (phase != null)
{
patterns = getPatternsForPhase( phase );
logger.debug(" Validating for phase: " + phase);
}
else
{
patterns = schema_.getPattern();
logger.debug(" Validating all patterns. No phase provided ");
}
ValidationResult vres = new ValidationResult();
// create the JXPathContext
// which will be used to validate each rule
JXPathContext jxpContext = JXPathContext.newContext( jbean );
Iterator iter = patterns.iterator ();
while (iter.hasNext ())
{
Pattern resultPattern = evalPattern( jxpContext, (Pattern) iter.next());
// if the resultPattern is null,
// then it passed successfully
if ( resultPattern != null) vres.addPattern( resultPattern );
}
return vres;
}
/**
* return the list of patterns listed
* as <active/> elements of <phase/>
*
* @param phase name of the phase
* @return List of patterns
*/
protected List getPatternsForPhase( String phase )
{
return (List) phaseMap_.get( phase );
}
/**
* Returns pattern with rules which failed during validation.
* The context attribute of each rule in the result pattern
* contains the exact location of the failed element
* unlike the context attribute of the original pattern which
* is an XSLT production pattern
*
* @param jxpContext The JXPathContext being validated
* @param pattern The production schema pattern to be evaluated
* @return pattern with rules wich failed during validation.
*/
protected Pattern evalPattern( JXPathContext jxpContext, Pattern pattern)
{
// copy attributes
Pattern resultPattern = new Pattern();
resultPattern.setName( pattern.getName() );
resultPattern.setId( pattern.getId() );
// evaluate rules
Iterator iter = pattern.getRule().iterator();
while (iter.hasNext())
{
List failedRules = evalRule(jxpContext, (Rule) iter.next () );
// if there were failed rules
// add them to the list of other failed rules
if (failedRules.size () > 0)
{
failedRules.addAll ( resultPattern.getRule() );
resultPattern.setRule ( failedRules );
}
}
// if there are no failed rules return null
if (resultPattern.getRule().size() == 0) return null;
else return resultPattern;
}
/**
* Returns rules with asserts or reports which failed during validation.
* The context attribute of each rule in the result pattern
* contains the exact location of the failed element
* unlike the context attribute of the original pattern which
* is an XSLT production pattern
*
* @param jxpContext The JXPath context being validated
* @param rule The original pattern rule to be evaluated
* @return pattern with rules wich failed during validation.
*/
protected List evalRule( JXPathContext jxpContext, Rule rule )
{
List elements = jxpContext.locate( rule.getContext() );
List failedRules = new ArrayList();
Iterator pointerIter = elements.iterator ();
while ( pointerIter.hasNext() )
{
Pointer ptr = (Pointer) pointerIter.next ();
// prepare result Rule
Rule nextFailedRule = new Rule();
nextFailedRule.setContext( ptr.asPath() );
// switch to the context of the rule
JXPathContext localJxpContext = JXPathContext.newContext( jxpContext,
ptr.getValue() );
// evaluate asserts
Iterator assertIter = rule.getAssert().iterator();
while (assertIter.hasNext())
{
Assert assert = (Assert) assertIter.next();
// if an assert test fails, then it should be added
// to the result
boolean passed = evalTest( localJxpContext, assert.getTest() );
if (!passed)
{
nextFailedRule.addAssert ( assert );
}
}
// evaluate reports
Iterator reportIter = rule.getReport().iterator();
while (reportIter.hasNext())
{
Report report = (Report) reportIter.next();
// if a report test passes, then it should be added
// to the result
boolean passed = evalTest( localJxpContext, report.getTest() );
if (passed)
{
nextFailedRule.addReport ( report );
}
}
// if the nextFailedRule is non empty,
// then add it to the list of failed rules
if (nextFailedRule.getAssert().size() > 0 ||
nextFailedRule.getReport().size() > 0)
{
failedRules.add( nextFailedRule );
}
}
return failedRules;
}
/**
* Test an XPath expression in a context
*
* @param jxpContext The JXPath context being validated
* @param String The XPath expression
* @return boolean result of evaluation
*/
protected boolean evalTest( JXPathContext jxpContext, String test )
{
Boolean passed = (Boolean) jxpContext.getValue( test, Boolean.class);
return passed.booleanValue ();
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ZSchematronTest.java
Index: ZSchematronTest.java
===================================================================
package org.apache.cocoon.validation.schematron;
// Java classes
import java.util.Iterator;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.File;
// XML classes
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.TransformerException;
import org.xml.sax.InputSource;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
// java classes
import java.util.Properties;
import org.apache.cocoon.samples.xmlform.TestBean;
/** Test class for the Schematron Java API */
public class ZSchematronTest
{
/**
* Method main
*/
public static void main(String args[])
throws Exception
{
System.out.println("\n=== Java based Schematron validation ===");
if (args.length < 1) {
System.err.println("Usage: java Schematron <schema.xml> " +
"[phase] ");
return;
}
// set preprocessor parameters
Properties params = new Properties();
if (args.length > 1)
params.put("phase", new String(args[1]));
// use custom schema
File file = new File( args[0] );
if ( !file.exists () ) throw new Exception("Error: schema file not
found !");
InputStream istrm = new FileInputStream ( file );
InputSource is = new InputSource ( istrm );
Validator validator = new Validator( is );
TestBean tbean = new TestBean();
// measure validation speed
long time = System.currentTimeMillis ();
int i = 0;
ValidationResult result = null;
for (; i < 100; i++)
{
// perform validation
result = validator.validate( tbean, params );
}
time = System.currentTimeMillis () - time;
System.out.println( "\nValidation performance:");
System.out.println( i + " cycles for " + time + " ms");
System.out.println( "Avarage validation time: " + (time/i) + " ms per
cycle " );
// everything ok?
if (result.isEmpty())
{
System.out.println("\nValidation ok, no messages generated");
}
else {
System.out.println("Validation encountered errors. Messages :");
Iterator piter = result.getPattern().iterator();
while (piter.hasNext ())
{
Pattern pattern = (Pattern)piter.next ();
System.out.println("Pattern name: " + pattern.getName() + ", id: "
+ pattern.getId() );
Iterator ruleIter = pattern.getRule().iterator();
while (ruleIter.hasNext ())
{
Rule rule = (Rule)ruleIter.next ();
System.out.println(" Rule name: " + rule.getContext() );
Iterator assertIter = rule.getAssert().iterator();
while (assertIter.hasNext ())
{
Assert assert = (Assert)assertIter.next ();
System.out.println(" Assert test: " + assert.getTest() +
", message: " + assert.getMessage() );
}
assertIter = rule.getReport().iterator();
while (assertIter.hasNext ())
{
Assert assert = (Assert)assertIter.next ();
System.out.println(" Report test: " + assert.getTest() +
", message: " + assert.getMessage() );
}
}
}
}
System.out.println("\n=== Schematron validation done ===");
}
}
1.1
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/xmlform/FormBeanBinder.java
Index: FormBeanBinder.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/xmlform/FormBeanBinder.java,v
1.1 2002/04/04 06:21:50 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/04/04 06:21:50 $
*
* ====================================================================
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Plotnix, Inc,
* <http://www.plotnix.com/>.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.cocoon.xmlform;
import java.util.Enumeration;
import java.util.Collection;
import org.apache.cocoon.environment.Request;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
/**
* <p>
* Binds an HTML Form to a JavaBean or DOM node.
* Expects that all request parameter names are XPath expressions to
properties of the bean.
* For each request parameter, finds and assigns its value to the
* JavaBean property corresponding to the parameter's name
* @todo provide a simple example
* </p>
*
*
* @author Ivelin Ivanov
* @version $Revision: 1.1 $ $Date: 2002/04/04 06:21:50 $
*/
public class FormBeanBinder
{
/**
* bind request parameters to JavaBean properties
* or DOM nodes
* @param request the submitetd HttpServletRequest
* @param jBean the bean which this method populates from the request
*/
public static void bind(Request request, Object jBean)
{
JXPathContext context = JXPathContext.newContext(jBean);
context.setLenient( false );
Enumeration enum = request.getParameterNames ();
while (enum.hasMoreElements ())
{
String path = (String) enum.nextElement ();
Object[] values = request.getParameterValues ( path );
Pointer pointer = context.locateValue( path );
Object property = pointer.getValue();
// if the property is a collection, set value as array
if ( property instanceof Collection )
{
pointer.setValue( values );
}
// otherwise set the value of the first element (there shouldn't be
other)
// in the values array
else
{
pointer.setValue( values[0] );
}
} // while
}
}
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/README.txt
Index: README.txt
===================================================================
The cocoon-form extension mechanism is inspired by Struts and XForms and is
intended to:
* Ease the development of sophisticated web applications utilizing with
complex data types and multi-page transactions
* Provide an automated 2 way mapping between HTML Forms <-> XML <-> JavaBeans
* Use the standardized and powerful XML Schema language for data validation
* Promote natural reuse of validation, binding and business logic between
cocoon actions (which are best utilized
for interactive clients driven web applications ) and web services (which are
in turn becoming the standard machine-to-machine web technology)
* In doing so, utilize as much as possible of the existing cocoon 2
technology. More specifically: actions, action sets, cocoon-form format.
--------------------------------------------------------------------------------------------
The current implementation offers the following features:
1) Automated 2 way binding of HTML Forms to JavaBeans (and DOM nodes) through
XPath
2) Automatic validation of JavaBeans(and DOM nodes) through Schematron schemas
--------------------------------------------------------------------------------------------
To try the demos, link to:
http://localhost:8080/cocoon/mount/xmlform/demo1
http://localhost:8080/cocoon/mount/xmlform/demo2
--------------------------------------------------------------------------------------------
For questions contact:
Ivelin Ivanov, [EMAIL PROTECTED] or [EMAIL PROTECTED]
--------------------------------------------------------------------------------------------
Following are copies of the announcement emails send to the Cocoon
development mailing list.
[email protected] <[email protected]>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----- Original Message -----
From: "Ivelin Ivanov" <[EMAIL PROTECTED]>
To: <[email protected]>
Cc: "Sam Robertson" <[EMAIL PROTECTED]>; "Torsten Curdt" <[EMAIL PROTECTED]>;
"Dmitri Plotnikov" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL
PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>
Sent: Thursday, March 14, 2002 3:31 PM
Subject: [Announcement] HTML Form binding and validation arrived
===============================================================
! The HTML Form symmetry loop is closed: !
===============================================================
HTML Forms <-> XPath <-> JavaBeans <-> XML -> Schematron -> HTML Forms
===============================================================
Just released the next version of the symmetric Form binding and validation
toolkit ( a CocoonBlock wannabe :).
In addition to the form-binding it now has integrated Schematron validation
support.
The zip file can be downloaded from:
http://prdownloads.sourceforge.net/freebuilder/CocoonForm_0-6.zip
With this in place one can provide form binding with just a few lines of
code (~5 lines) and Sophisticated form validation with 0! lines of Java
code.
Let me walk you quickly through the sitemap of the example provided in the
distribution:
#########
#sitemap:#
########
...
<map:pipelines>
<map:pipeline>
<map:match pattern="*">
1. <map:act type="FormBinderAction"/> <!-- ### Uses The
FormBeanBinder tool to bind the html form elements to an underlying JavaBean
model through XPath based form element names -->
2. <map:generate src="insertFormBean.xml"/> <!-- ### This is a very
short
files simply inserting the form bean -->
3. <map:transform type="castor"/> <!-- ###
CastorTransformer converts the bean into an XML stream -->
4. <map:transform src="schematron/xmlform-sch-report.xsl"/> <!-- ### A
Schematron schema validates the form and adds the validation results in the
stream, while preserving the original form stream -->
5. <map:transform src="formbean2html.xsl"/> <!-- ### Renders the HTML
file
using the XML form and the validation errors from the input document -->
<map:serialize type="html"/>
</map:match>
</map:pipeline>
</map:pipelines>
...
######################
#xmlform-sch-report.xml: #
######################
The validation schema is really simple and intuitive. The one in the example
is over simplified.
Schematron however supports i18n and validation in phases (useful for
wizards).
...
<schema ns="http://xml.apache.cocoon/xmlform"
xmlns="http://www.ascc.net/xml/schematron">
<title>Schema for the XML Form example</title>
<pattern name="A Simple Form Validation Pattern">
<rule context="name">
<assert test="string-length(.) > 3">Animal name should be at least 4
characters.</assert>
<assert test="string-length(.) < 10">Animal name should be less than
10 characters.</assert>
</rule>
<rule context="scope">
<assert test="normalize-space(.) = 'session' or normalize-space(.) =
'request'">Scope should be request or session.</assert>
</rule>
</pattern>
</schema>
=====================================
That's all folks !
All sources and xml documents are provided in the example.
I will be working with Torsten on a more sophisticated wizard example
and a best practices document.
Cocoon is really close to becoming a full-blown web-app server,
which enforces a pure separation in BOTH directions !
I know everyone on this team is extremely busy, but even one line feedback
is of great help for me, so
Feedback please !
Cheers,
Ivelin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----- Original Message -----
From: "Ivelin Ivanov" <[EMAIL PROTECTED]>
To: <[email protected]>
Cc: "Oliver Becker" <[EMAIL PROTECTED]>; "Rick Jelliffe" <[EMAIL PROTECTED]>;
"Dmitri Plotnikov" <[EMAIL PROTECTED]>
Sent: Sunday, March 24, 2002 7:03 AM
Subject: [Announcement] Fast Schematron Validation Here !
We've got the rainbow !
+===========================================+
+ *Fast* Java API for Schematron Validation *Ready* ! +
+===========================================+
+ Validates both JavaBeans and DOM nodes +
+===========================================+
It's been another long and fruitful Saturday here in Austin...
I am grateful to everyone in the Cocoon community as well as Dmitri
Plotnikov for his help with JXPath, Rick Jelliffe for his guidance with
Schematron and Oliver Becker for the clarifications on his XSLT based Java
API for Schematron.
As I mentioned already, I've decided to implement Schematron in Java using
JXPath.
The result is surprisingly little code (~1K lines) and quite exciting speed
(~20ms per validation for the demo setup).
What's more:
- Does not need Castor mapping
- Does not do XSL transformation
- Direct access through the JXPath library
* Someone let me know if this can be implemented too much faster *
I hope this answers some outstanding questions like:
"How do we validate HTML Forms ?"
"How do we reuse validation rules and code for HTML Forms, Web Services and
domain validation ?"
"What language do we use or build to implement validation?"
I am not sure if the credits should all go to Schematron or more to XPath,
but
Schematron being so simple and powerful is clearly my choice:
- Schemas can grow organicly. One can start with a few simple rules and grow
the document with time.
- Native support for validation in "phases". Unlike XML Schema, one doesn't
need to provide a complete document in order to be able to perform
validation.
- Pin-points the bad elements and provides user-friendly reporting.
- Very, very simple to learn if one knows XPath. (I just can stop repeating
that.)
Please play with the new demo and send me your feedback.
I've tried to add more JavaDoc since last time.
Note that since there are 2 demos now, the URLs are different:
xmlform/demo1 for the original demo and
xmlform/demo2 for the new demo
The new demo extends the first one with an additional page which is shown on
successful submit.
This shows a possible sitemap control logic based on validation results.
Having in addition the efficient HTML Form -> JavaBean binding, I'm
convinced we're not too far from making Cocoon a prime time app server.
The only area which is not completely fleshed out yet is rendering the HTML
Forms.
The currently proposed simplistic solution apparently works for many people,
but there are still strong opinons for a
XForms style model. I would need more specific suggestions on the latter, so
that we can have a good understanding
and eventually vote on one or the other.
Download from:
http://prdownloads.sourceforge.net/freebuilder/CocoonForm_0-7.zip
========================
P.S.: For those who are too busy to install the demo, but would like to
participate in the discussion, I attach key snippets of code below:
========================
----------------------------------------------------------------
sitemap.xmap:
...
<!--
Demo2:
1) The Action binds the HTML form to a JavaBean
and inserts it in the session
2) The Action uses the Java Schematron Validator
to perform fast validation
3) The Action inserts into request the validation
result (if negative)
4) Selector branches control depending on the
outcome of 3)
5) If 3) produced validation errors, then the path
is similar to Demo1
6) If 3) did not produce validation errors, then
Success page is displayed
-->
<map:match pattern="demo2">
<map:act type="ValidationFormAction"/>
<map:select type="request-attribute">
<map:parameter name="attribute-name"
value="validationPassed"/>
<!-- validation passed, go to next page -->
<map:when test="true">
<map:call resource="display-success"/>
</map:when>
<!-- validation failed, go to the same
page -->
<map:otherwise>
<map:generate
src="insertFormBean-Demo2.xml"/>
<map:transform type="castor"/>
<map:transform
src="formbean2html-Demo2.xsl"/>
<map:serialize type="html"/>
</map:otherwise>
</map:select>
</map:match>
</map:pipeline>
...
----------------------------------------------------------------
class ValidatingFormAction
...
public Map act(...)
{
...
String formName = "xmlForm";
TestBean jBean = (TestBean) session.getAttribute( formName );
if (jBean == null)
{
// first time here, populate the bean with initial values
jBean = new TestBean();
session.setAttribute( formName, jBean);
}
else
{
// been here before, update the bean with client's values
FormBeanBinder.bind(request, jBean);
}
// validate state of the bean against a Schematron schema.
// Schema Phase is "Full"
Properties props = new Properties();
props.put("phase", "Full");
ValidationResult vres = validator_.validate(jBean, props);
// if the validation result is not empty, then
// make the validation result available to the pipeline
// it can be later checked by a <map:selector/>
// or inserted in the SAX stream by a CastorTransformer
// or maybe even both
if (!vres.isEmpty())
{
request.setAttribute ( formName + "ValidationResult", vres );
}
request.setAttribute ( "validationPassed", new Boolean(
vres.isEmpty() ) );
// apply additional buziness logic to the bean
jBean.incrementCount();
return objectModel;
}
...
}
Ivelin
~~~~~~~~~~~~~~~~~~~~~
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/formbean2html-Demo2.xsl
Index: formbean2html-Demo2.xsl
===================================================================
<xsl:stylesheet
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xform="http://xml.apache.cocoon/xmlform"
version = "1.0" >
<xsl:output method = "html" omit-xml-declaration = "yes" />
<xsl:template match = "/*" >
<html>
<body>
Please edit and submit: <br/>
<xsl:apply-templates select="/xmlform/instance/*"/>
<hr/>
<p>
Copy of input document (sorry for the lousy format, view source to
see the xml):
<pre>
<xsl:copy-of select="."/>
</pre>
</p>
</body>
</html>
</xsl:template>
<xsl:template match = "animal" >
<form method="post" action="demo2">
<xsl:variable name="animalName" select="name"/>
Animal name: <input type="text" name="name" value="{$animalName}"/>
(hint: try submitting name < 4 or > 10 characters)
<xsl:call-template name="showErrors">
<xsl:with-param name="element">/name</xsl:with-param>
</xsl:call-template>
<br/>
Kind: <b><xsl:value-of select="personalInfo/@kind"/></b>
<br/>
<xsl:variable name="animalScope" select="scope"/>
Animal scope: <input type="text" name="scope"
value="{$animalScope}"/>
(hint: try submitting scope != session or request)
<xsl:call-template name="showErrors">
<xsl:with-param name="element">/scope</xsl:with-param>
</xsl:call-template>
<br/>
<xsl:variable name="preference1" select="preferences[1]"/>
First Preference: <input type="text" name="preferences[1]"
value="{$preference1}"/>
<br/>
<xsl:variable name="preference2" select="preferences[2]"/>
Second Preference: <input type="text" name="preferences[2]"
value="{$preference2}"/>
<br/>
<input type="submit"/>
</form>
<br/>
Counter: <xsl:value-of select="@count"/>
</xsl:template>
<xsl:template name = "showErrors">
<xsl:param name = "element" />
<xsl:for-each select="/xmlform/validationResult/pattern/[EMAIL
PROTECTED]/assert">
<br/>
<font color="red">
* <xsl:value-of select="."/>
</font>
</xsl:for-each>
<xsl:for-each select="/xmlform/validationResult/pattern/[EMAIL
PROTECTED]/report">
<br/>
<font color="red">
* <xsl:value-of select="."/>
</font>
</xsl:for-each>
</xsl:template>
<xsl:template match = "*" />
</xsl:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/formbean2html.xsl
Index: formbean2html.xsl
===================================================================
<xsl:stylesheet
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xform="http://xml.apache.cocoon/xmlform"
version = "1.0" >
<xsl:output method = "html" omit-xml-declaration = "yes" />
<xsl:template match = "/*" >
<html>
<body>
Please edit and submit: <br/>
<xsl:apply-templates select="/xmlform/instance/*"/>
<hr/>
<p>
Copy of input document (sorry for the lousy format, view source to
see the xml):
<pre>
<xsl:copy-of select="."/>
</pre>
</p>
</body>
</html>
</xsl:template>
<xsl:template match = "animal" >
<form method="post" action="demo1">
<xsl:variable name="animalName" select="name"/>
Animal name: <input type="text" name="name" value="{$animalName}"/>
(hint: try submitting name < 4 or > 10 characters)
<xsl:call-template name="showErrors">
<xsl:with-param name="element">animal/name</xsl:with-param>
</xsl:call-template>
<br/>
Kind: <b><xsl:value-of select="personalInfo/@kind"/></b>
<br/>
<xsl:variable name="animalScope" select="scope"/>
Animal scope: <input type="text" name="scope"
value="{$animalScope}"/>
(hint: try submitting scope != session or request)
<xsl:call-template name="showErrors">
<xsl:with-param name="element">animal/scope</xsl:with-param>
</xsl:call-template>
<br/>
<xsl:variable name="preference1" select="preferences[1]"/>
First Preference: <input type="text" name="preferences[1]"
value="{$preference1}"/>
<br/>
<xsl:variable name="preference2" select="preferences[2]"/>
Second Preference: <input type="text" name="preferences[2]"
value="{$preference2}"/>
<br/>
<input type="submit"/>
</form>
<br/>
Counter: <xsl:value-of select="@count"/>
</xsl:template>
<xsl:template name = "showErrors">
<xsl:param name = "element" />
<xsl:for-each
select="/xmlform/validationResult/pattern/error[path=$element]">
<br/>
<font color="red">
* <xsl:value-of select="message"/>
</font>
</xsl:for-each>
</xsl:template>
<xsl:template match = "*" />
</xsl:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/insertFormBean-Demo2.xml
Index: insertFormBean-Demo2.xml
===================================================================
<?xml version="1.0"?>
<xmlform
xmlns:xform="http://xml.apache.cocoon/xmlform"
xmlns:castor="http://castor.exolab.org/cocoontransfomer">
<instance>
<castor:InsertBean name="xmlForm"/>
</instance>
<castor:InsertBean name="xmlFormValidationResult"/>
</xmlform>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/insertFormBean.xml
Index: insertFormBean.xml
===================================================================
<?xml version="1.0"?>
<xmlform
xmlns:xform="http://xml.apache.cocoon/xmlform"
xmlns:castor="http://castor.exolab.org/cocoontransfomer">
<instance>
<castor:InsertBean name="xmlform"/>
</instance>
</xmlform>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<!-- =========================== Components
================================ -->
<map:components>
<map:generators default="file"/>
<map:transformers default="xslt">
<map:transformer name="castor"
src="org.apache.cocoon.transformation.CastorTransformer">
<mapping>castor-mappings/test-mapping.xml</mapping>
</map:transformer>
</map:transformers>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:selectors default="browser"/>
<map:matchers default="wildcard">
<map:matcher name="wildcard"
src="org.apache.cocoon.matching.WildcardURIMatcherFactory"/>
</map:matchers>
<map:actions>
<map:action name="FormBinderAction"
src="org.apache.cocoon.samples.xmlform.FormBinderAction"/>
<map:action name="ValidationFormAction"
src="org.apache.cocoon.samples.xmlform.ValidatingFormAction"/>
</map:actions>
</map:components>
<!-- =========================== Resources
================================= -->
<!--
Display confirmation page for test2
-->
<map:resources>
<map:resource name="display-success">
<map:generate src="success-page-Demo2.html"/>
<map:serialize type="html"/>
</map:resource>
</map:resources>
<!-- =========================== Pipelines
================================= -->
<map:pipelines>
<map:pipeline internal-only="false">
<!--
Validating XSLT generator
Generates a Schematron Validating XSLT
from your schematron-[doctype].xml file
Dynamic internal pipeline for Schematron schemas
originally
proposed by Jeremy Quinn <[EMAIL PROTECTED]>
-->
<map:match pattern="make-validator">
<map:generate src="schematron/xmlform-sch-report.xml"/>
<map:transform src="schematron/xmlform-schematron.xsl"/>
<map:serialize type="xml"/>
</map:match>
</map:pipeline>
<map:pipeline>
<!--
Demo1:
1) The Action binds the HTML form to a JavaBean and
inserts it in the session
2) CastorTransformer inserts the JavaBean into the
SAX stream
3) Schematron stylesheet validates data and adds
results to the SAX stream
4) Stylesheet displays form and errors based on the
output from 3)
-->
<map:match pattern="demo1">
<map:act type="FormBinderAction"/>
<map:generate src="insertFormBean.xml"/>
<map:transform type="castor"/>
<map:transform src="cocoon:/make-validator"/>
<!-- map:transform
src="schematron/xmlform-sch-report.xsl"/ -->
<map:transform src="formbean2html.xsl"/>
<map:serialize type="html"/>
</map:match>
<!--
Demo2:
1) The Action binds the HTML form to a JavaBean and
inserts it in the session
2) The Action uses the Java Schematron Validator to
perform fast validation
3) The Action inserts into request the validation
result (if negative)
4) Selector branches control depending on the
outcome of 3)
5) If 3) produced validation errors, then the path
is similar to Demo1
6) If 3) did not produce validation errors, then
Success page is displayed
-->
<map:match pattern="demo2">
<map:act type="ValidationFormAction"/>
<map:select type="request-attribute">
<map:parameter name="attribute-name"
value="validationPassed"/>
<!-- validation passed, go to next page -->
<map:when test="true">
<map:call resource="display-success"/>
</map:when>
<!-- validation failed, go to the same page
-->
<map:otherwise>
<map:generate
src="insertFormBean-Demo2.xml"/>
<map:transform type="castor"/>
<map:transform
src="formbean2html-Demo2.xsl"/>
<map:serialize type="html"/>
</map:otherwise>
</map:select>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
<!-- end of file -->
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/success-page-Demo2.html
Index: success-page-Demo2.html
===================================================================
<html>
<body>
Congratulations!
<br/>
Your form was processed successfully.
<br/>
<a href="demo2?reset=true">Go back to first page.</a>
</body>
</html>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/castor-mappings/test-mapping.xml
Index: test-mapping.xml
===================================================================
<mapping>
<class name="org.apache.cocoon.samples.xmlform.TestBean">
<map-to xml="animal"/>
<field name="name" type="java.lang.String">
<bind-xml name="name" node="element"/>
</field>
<field name="scope" type="java.lang.String">
<bind-xml name="scope" node="element"/>
</field>
<field name="count" type="integer">
<bind-xml name="count" node="attribute"/>
</field>
<field name="Preferences"
collection="collection">
<bind-xml name="preferences"/>
</field>
<field name="PersonalInfo"
type="org.apache.cocoon.samples.xmlform.NestedBean">
<bind-xml name="personalInfo" node="element"/>
</field>
</class>
<class name="org.apache.cocoon.samples.xmlform.NestedBean">
<map-to xml="personalInfo"/>
<field name="kind"
type="java.lang.String">
<bind-xml name="kind" node="attribute"/>
</field>
</class>
<!-- mapping for Schematron ValidationResult -->
<class
name="org.apache.cocoon.validation.schematron.ValidationResult">
<map-to xml="validationResult"/>
<field name="pattern"
type="org.apache.cocoon.validation.schematron.Pattern"
collection="collection">
<bind-xml name="pattern"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.Phase">
<map-to xml="phase"/>
<field name="id" type="java.lang.String">
<bind-xml name="id" node="attribute"/>
</field>
<field name="active"
type="org.apache.cocoon.validation.schematron.ActivePattern"
collection="collection">
<bind-xml name="active"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.ActivePattern">
<map-to xml="active"/>
<field name="pattern" type="java.lang.String">
<bind-xml name="id" node="attribute"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.Pattern">
<map-to xml="pattern"/>
<field name="name" type="java.lang.String">
<bind-xml name="name" node="attribute"/>
</field>
<field name="id" type="java.lang.String">
<bind-xml name="id" node="attribute"/>
</field>
<field name="rule"
type="org.apache.cocoon.validation.schematron.Rule"
collection="collection">
<bind-xml name="rule"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.Rule">
<map-to xml="rule"/>
<field name="context" type="java.lang.String">
<bind-xml name="context" node="attribute"/>
</field>
<field name="assert"
type="org.apache.cocoon.validation.schematron.Assert"
collection="collection">
<bind-xml name="assert"/>
</field>
<field name="report"
type="org.apache.cocoon.validation.schematron.Report"
collection="collection">
<bind-xml name="report"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.Assert">
<map-to xml="assert"/>
<field name="test" type="java.lang.String">
<bind-xml name="test" node="attribute"/>
</field>
<field name="message" type="java.lang.String">
<bind-xml node="text"/>
</field>
</class>
<class name="org.apache.cocoon.validation.schematron.Report">
<map-to xml="report"/>
<field name="test" type="java.lang.String">
<bind-xml name="test" node="attribute"/>
</field>
<field name="message" type="java.lang.String">
<bind-xml node="text"/>
</field>
</class>
</mapping>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/schematron1-5.xsd
Index: schematron1-5.xsd
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- schemaVersion of 2001/02/15 -->
<xsd:schema
targetNamespace="http://www.ascc.net/xml/schematron"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns="http://www.ascc.net/xml/schematron"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
version="+//IDN sinica.edu.tw//SGML W3C XML Schema for Schematron
1.5//EN">
<xsd:annotation>
<xsd:documentation
source="http://www.ascc.net/xml/resource/schematron/schematron.html"
xml:lang="en"/>
</xsd:annotation>
<xsd:element name="active">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:dir"/>
<xsd:element ref="sch:emph"/>
<xsd:element ref="sch:span"/>
</xsd:choice>
<xsd:attribute name="pattern" type="xsd:ID"
use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="assert">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:name"/>
<xsd:element ref="sch:emph"/>
<xsd:element ref="sch:dir"/>
<xsd:element ref="sch:span"/>
<xsd:any namespace="##other"
processContents="lax"/>
</xsd:choice>
<xsd:attribute name="test" type="xsd:string"
use="required"/>
<xsd:attribute name="role" type="xsd:NMTOKEN"/>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="diagnostics" type="xsd:IDREFS"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
<xsd:attribute name="subject" type="xsd:string"
use="default" value="."/>
<xsd:anyAttribute namespace="##other"
processContents="lax"/>
<!--xsd:attribute name="xml:lang" type="xsd:language"
-->
</xsd:complexType>
</xsd:element>
<xsd:element name="diagnostic">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:value-of"/>
<xsd:element ref="sch:emph"/>
<xsd:element ref="sch:dir"/>
<xsd:element ref="sch:span"/>
<xsd:any namespace="##other"
processContents="lax"/>
</xsd:choice>
<xsd:attribute name="id" type="xsd:ID" use="required"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
<xsd:anyAttribute namespace="##other"
processContents="lax"/>
<!--xsd:attribute name="xml:lang" type="xsd:language"
-->
</xsd:complexType>
</xsd:element>
<xsd:element name="diagnostics">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="diagnostic" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="dir">
<xsd:complexType>
<xsd:simpleContent>
<xsd:restriction base="xsd:string">
<xsd:attribute name="value">
<xsd:simpleType>
<xsd:restriction
base="xsd:NMTOKEN">
<xsd:enumeration value="ltr"/>
<xsd:enumeration value="rtl"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="emph" type="xsd:string"/>
<xsd:element name="extends">
<xsd:complexType>
<xsd:attribute name="rule" type="xsd:IDREF"
use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="key">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:NMTOKEN"
use="required"/>
<xsd:attribute name="path" type="xsd:string"
use="required"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="name">
<xsd:complexType>
<xsd:attribute name="path" type="xsd:string"
use="default" value="."/>
</xsd:complexType>
</xsd:element>
<xsd:element name="ns">
<xsd:complexType>
<xsd:attribute name="uri" type="xsd:uriReference"
use="required"/>
<xsd:attribute name="prefix" type="xsd:NCName"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="p">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:dir"/>
<xsd:element ref="sch:emph"/>
<xsd:element ref="sch:span"/>
</xsd:choice>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="class" type="xsd:string"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
<xsd:anyAttribute namespace="##other"
processContents="lax"/>
<!--xsd:attribute name="xml:lang" type="xsd:language"
-->
</xsd:complexType>
</xsd:element>
<xsd:element name="pattern">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="p" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:rule"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string"
use="required"/>
<xsd:attribute name="see" type="xsd:uriReference"/>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="phase">
<xsd:complexType>
<xsd:sequence >
<xsd:element ref="sch:p" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:active"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID" use="required"/>
<xsd:attribute name="fpi" type="xsd:string"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="report">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:name"/>
<xsd:element ref="sch:emph"/>
<xsd:element ref="sch:dir"/>
<xsd:element ref="sch:span"/>
<xsd:any namespace="##other"
processContents="lax"/>
</xsd:choice>
<xsd:attribute name="test" type="xsd:string"
use="required"/>
<xsd:attribute name="role" type="xsd:NMTOKEN"/>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="diagnostics" type="xsd:IDREFS"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
<xsd:attribute name="subject" type="xsd:string"
use="default" value="."/>
</xsd:complexType>
</xsd:element>
<xsd:element name="rule">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="sch:assert"/>
<xsd:element ref="sch:report"/>
<xsd:element ref="sch:key"/>
<xsd:element ref="sch:extends"/>
</xsd:choice>
<xsd:attribute name="context" type="xsd:string"/>
<xsd:attribute name="abstract" type="xsd:boolean"
use="default" value="false"/>
<xsd:attribute name="role" type="xsd:NMTOKEN"/>
<xsd:attribute name="id" type="xsd:ID"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="schema">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="sch:title" minOccurs="0"/>
<xsd:element ref="sch:ns" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:p" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:phase" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:pattern"
maxOccurs="unbounded"/>
<xsd:element ref="sch:p" minOccurs="0"
maxOccurs="unbounded"/>
<xsd:element ref="sch:diagnostics"
minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="fpi" type="xsd:string"/>
<xsd:attribute name="schemaVersion" type="xsd:string"/>
<xsd:attribute name="defaultPhase" type="xsd:IDREF"/>
<xsd:attribute name="icon" type="xsd:uriReference"/>
<xsd:attribute name="ns" type="xsd:uriReference"/>
<xsd:attribute name="version" type="xsd:string"
use="default" value="1.5"/>
<xsd:anyAttribute namespace="##other"
processContents="lax"/>
<!--xsd:attribute name="xml:lang" type="xsd:language"
-->
</xsd:complexType>
</xsd:element>
<xsd:element name="span">
<xsd:complexType>
<xsd:simpleContent>
<xsd:restriction base="xsd:string">
<xsd:attribute name="class"
type="xsd:string"/>
</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="title">
<xsd:complexType mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="sch:dir"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:element name="value-of">
<xsd:complexType>
<xsd:attribute name="select" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/some-xmlform.xml
Index: some-xmlform.xml
===================================================================
<?xml version="1.0"?>
<xmlform
xmlns:xform="http://xml.apache.cocoon/xmlform"
xmlns:castor="http://castor.exolab.org/cocoontransfomer">
<instance>
<animal>
<name>Mickey Mouse</name>
<scope>session1</scope>
<personalInfo>
<kind>mammal</kind>
</personalInfo>
<count>10d</count>
</animal>
</instance>
</xmlform>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-extensions.xsl
Index: xmlform-extensions.xsl
===================================================================
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns:aaa="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:zvon="http://zvon.org/schematron">
<xsl:template name="fullPath">
<aaa:template match="*|@*" mode="fullPath">
<aaa:apply-templates select="parent::*" mode="fullPath"/>
<aaa:text>/</aaa:text>
<aaa:if test="count(. | ../@*) = count(../@*)">@</aaa:if>
<aaa:value-of select="name()"/>
<aaa:if test="preceding-sibling::*[name()=name(current())] or
following-sibling::*[name()=name(current())]">
<aaa:text>[</aaa:text>
<aaa:value-of
select="1+count(preceding-sibling::*[name()=name(current())])"/>
<aaa:text>]</aaa:text>
</aaa:if>
</aaa:template>
</xsl:template>
</xsl:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-sch-report-Demo2.xml
Index: xmlform-sch-report-Demo2.xml
===================================================================
<?xml version="1.0" ?>
<!--
Schematron schema for the xml form example
Ivelin Ivanov, [EMAIL PROTECTED]
-->
<schema ns="http://xml.apache.cocoon/xmlform"
xmlns="http://www.ascc.net/xml/schematron">
<title>Schema for the XML Form example</title>
<phase id="New">
<p>For creating new documents.</p>
<active pattern="mini"/>
</phase>
<phase id="Draft">
<p>For fast validation of draft documents.</p>
<active pattern="required" />
</phase>
<phase id="Full">
<p>For final validation and tracking some tricky problems.</p>
<active pattern="mini" />
<active pattern="required" />
<active pattern="extra" />
</phase>
<pattern name="A Simple Validation Pattern" id="mini">
<rule context="name">
<assert test="string-length(.) > 3" diagnostics="dname
dcount">Animal name should be at least 4 characters.</assert>
<assert test="string-length(.) < 10">Animal name
should be less than 10 characters.</assert>
</rule>
<rule context="scope">
<assert test="normalize-space(.) = 'session' or
normalize-space(.) = 'request'">Scope should be request or session.</assert>
</rule>
</pattern>
<pattern name="Required Validation Pattern" id="required">
<rule context="count">
<assert test="number(.) > 0" diagnostics="dcount"> The
counter should be > 0.</assert>
</rule>
</pattern>
<pattern name="Extra Simple Validation Pattern" id="extra">
a pattern
<rule context="/personalInfo/type"> a rule
<assert test="text(.) = 'mammal'"> Animal type should
be mammal</assert>
<report test="text(.) != 'mammal'"> Animal is not
mammal</report>
</rule>
</pattern>
<diagnostics>
<diagnostic id="dname">
Animals rarely have names shorter than 5 characters.
Dog and Cat are among the rare exceptions.
All right, all right, don't hold me to these words, this is
just a sloppy test after all.
</diagnostic>
<diagnostic id="dcount">
The animal counter simply keeps track of the number of times
this animal was visited .
</diagnostic>
</diagnostics>
</schema>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-sch-report.xml
Index: xmlform-sch-report.xml
===================================================================
<?xml version="1.0" ?>
<!--
Schematron schema for the xml form example
Ivelin Ivanov, [EMAIL PROTECTED]
-->
<schema ns="http://xml.apache.cocoon/xmlform"
xmlns="http://www.ascc.net/xml/schematron">
<title>Schema for the XML Form example</title>
<pattern name="A Simple Form Validation Pattern">
<rule context="name">
<assert test="string-length(.) > 3">Animal name should
be at least 4 characters.</assert>
<assert test="string-length(.) < 10">Animal name
should be less than 10 characters.</assert>
</rule>
<rule context="scope">
<assert test="normalize-space(.) = 'session' or
normalize-space(.) = 'request'">Scope should be request or session.</assert>
</rule>
</pattern>
</schema>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-sch-report.xsl
Index: xmlform-sch-report.xsl
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<aaa:stylesheet xmlns:aaa="http://www.w3.org/1999/XSL/Transform"
xmlns:zvon="http://zvon.org/schematron"
xmlns:sch="http://www.ascc.net/xml/schematron" version="1.0">
<aaa:output indent="yes" method="xml"/>
<aaa:template match="/xmlform/instance/*">
<xmlform xmlns:xform="http://xml.apache.cocoon/xmlform">
<instance>
<aaa:copy-of select="."/>
</instance>
<validationResult>
<pattern name="A Simple Validation Pattern">
<aaa:apply-templates mode="N1002E" select="/xmlform/instance/*"/>
</pattern>
<pattern name="Required Validation Pattern">
<aaa:apply-templates mode="N10048" select="/xmlform/instance/*"/>
</pattern>
<pattern name="Extra Simple Validation Pattern">
<aaa:apply-templates mode="N10056" select="/xmlform/instance/*"/>
</pattern>
</validationResult>
</xmlform>
<aaa:message>
<aaa:apply-templates mode="startDiagnostics" select="/"/>
</aaa:message>
</aaa:template>
<aaa:template priority="10" mode="N1002E" match="name">
<aaa:if test="not(string-length(.) > 3)">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message>Animal name should be at least 4 characters.</message>
</error>
</aaa:if>
<aaa:if test="not(string-length(.) < 10)">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message>Animal name should be less than 10 characters.</message>
</error>
</aaa:if>
<aaa:apply-templates mode="N1002E" select="*|@*"/>
</aaa:template>
<aaa:template priority="10" mode="N1002E" match="scope">
<aaa:if test="not(normalize-space(.) = 'session' or normalize-space(.) =
'request')">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message>Scope should be request or session.</message>
</error>
</aaa:if>
<aaa:apply-templates mode="N1002E" select="*|@*"/>
</aaa:template>
<aaa:template priority="10" mode="N10048" match="count">
<aaa:if test="not(number(.) > 0)">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message> The counter should be > 0.</message>
</error>
</aaa:if>
<aaa:apply-templates mode="N10048" select="*|@*"/>
</aaa:template>
<aaa:template priority="10" mode="N10056" match="/personalInfo/type">
<aaa:if test="not(text(.) = 'mammal')">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message> Animal type should be mammal</message>
</error>
</aaa:if>
<aaa:if test="text(.) != 'mammal'">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates mode="fullPath" select="."/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '/xmlform/instance/')"/>
</path>
<message> Animal is not mammal</message>
</error>
</aaa:if>
<aaa:apply-templates mode="N10056" select="*|@*"/>
</aaa:template>
<aaa:template mode="N1002E" match="text()"/>
<aaa:template mode="N1002E" match="*|@*">
<aaa:apply-templates mode="N1002E" select="node()|@*"/>
</aaa:template>
<aaa:template mode="dia_N1002E" match="text()"/>
<aaa:template mode="dia_N1002E" match="*|@*">
<aaa:apply-templates mode="dia_N1002E" select="node()|@*"/>
</aaa:template>
<aaa:template mode="N10048" match="text()"/>
<aaa:template mode="N10048" match="*|@*">
<aaa:apply-templates mode="N10048" select="node()|@*"/>
</aaa:template>
<aaa:template mode="dia_N10048" match="text()"/>
<aaa:template mode="dia_N10048" match="*|@*">
<aaa:apply-templates mode="dia_N10048" select="node()|@*"/>
</aaa:template>
<aaa:template mode="N10056" match="text()"/>
<aaa:template mode="N10056" match="*|@*">
<aaa:apply-templates mode="N10056" select="node()|@*"/>
</aaa:template>
<aaa:template mode="dia_N10056" match="text()"/>
<aaa:template mode="dia_N10056" match="*|@*">
<aaa:apply-templates mode="dia_N10056" select="node()|@*"/>
</aaa:template>
<aaa:template mode="startDiagnostics" match="/xmlform/instance/*">
<aaa:apply-templates mode="dia_N1002E" select="/xmlform/instance/*"/>
<aaa:apply-templates mode="dia_N10048" select="/xmlform/instance/*"/>
<aaa:apply-templates mode="dia_N10056" select="/xmlform/instance/*"/>
</aaa:template>
<aaa:template name="diagnostic_dname">
Diagnostics:
Animals rarely have names shorter than 5 characters.
Dog and Cat are among the rare exceptions.
All right, all right, don't hold me to these words, this is
just a sloppy test after all.
</aaa:template>
<aaa:template name="diagnostic_dcount">
Diagnostics:
The animal counter simply keeps track of the number of times
this animal was visited .
</aaa:template>
<aaa:template priority="10" mode="dia_N1002E" match="name">
<aaa:if test="not(string-length(.) > 3)">
<aaa:call-template name="diagnostic_dname"/>
<aaa:call-template name="diagnostic_dcount"/>
</aaa:if>
</aaa:template>
<aaa:template priority="10" mode="dia_N10048" match="count">
<aaa:if test="not(number(.) > 0)">
<aaa:call-template name="diagnostic_dcount"/>
</aaa:if>
</aaa:template>
<aaa:template mode="fullPath" match="*|@*">
<aaa:apply-templates mode="fullPath" select="parent::*"/>
<aaa:text>/</aaa:text>
<aaa:if test="count(. | ../@*) = count(../@*)">@</aaa:if>
<aaa:value-of select="name()"/>
<aaa:if test="preceding-sibling::*[name()=name(current())] or
following-sibling::*[name()=name(current())]">
<aaa:text>[</aaa:text>
<aaa:value-of select="1+count(preceding-sibling::*[name()=name(current())])"/>
<aaa:text>]</aaa:text>
</aaa:if>
</aaa:template>
</aaa:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-schematron.xsl
Index: xmlform-schematron.xsl
===================================================================
<!-- sch:key moved as a child of sch:schema and syntax changed to xslt
usage -->
<!--
This stylesheet is derived from the original work of Miloslav Nic [ [EMAIL
PROTECTED] ]
http://www.zvon.org/xxl/SchematronTutorial/General/contents.html
It is offered in its current form by Ivelin Ivanov [ [EMAIL PROTECTED] ]
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns:aaa="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:zvon="http://zvon.org/schematron">
<xsl:import href="xmlform-wrappers.xsl"/>
<xsl:import href="xmlform-extensions.xsl"/>
<xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="xsl"/>
<xsl:output method="xml" indent="yes"/>
<xsl:param name="outputMethod">xml</xsl:param>
<!-- root of an XML Form document -->
<xsl:variable name="docRoot">/xmlform/instance/*</xsl:variable>
<xsl:key name="PHASE" match="sch:phase" use="sch:active/@pattern"/>
<xsl:template name="sch-pattern">
<xsl:apply-templates select="/sch:schema/sch:[EMAIL PROTECTED]/sch:[EMAIL
PROTECTED] = current()/@id]"/>
<xsl:apply-templates select="sch:p"/>
<aaa:apply-templates select="." mode="{generate-id(.)}"/>
</xsl:template>
<xsl:template match="sch:pattern">
<xsl:call-template name="patternWrapper"/>
</xsl:template>
<xsl:template match="sch:rule[not(@abstract='yes')]">
<xsl:variable name="md" select="generate-id(parent::sch:pattern)"/>
<aaa:template match="[EMAIL PROTECTED]" mode="{$md}" priority="10">
<xsl:apply-templates select="*|//sch:[EMAIL PROTECTED]'yes' and @id =
current()/sch:extends/@rule]/*"/>
<aaa:apply-templates select="*|@*" mode="{$md}"/>
</aaa:template>
</xsl:template>
<xsl:template match="sch:key" mode="defineKey">
<aaa:key name="[EMAIL PROTECTED]" match="[EMAIL PROTECTED]" use="[EMAIL
PROTECTED]"/>
<!-- <aaa:key name="[EMAIL PROTECTED]"
match="{parent::sch:rule/@context}" use="[EMAIL PROTECTED]"/> -->
</xsl:template>
<xsl:template match="sch:report | sch:assert">
<xsl:variable name="startNOT">
<xsl:if test="self::sch:assert">not(</xsl:if>
</xsl:variable>
<xsl:variable name="endNOT">
<xsl:if test="self::sch:assert">)</xsl:if>
</xsl:variable>
<aaa:if test="[EMAIL PROTECTED]">
<xsl:call-template name="reportAssertWrapper"/>
</aaa:if>
</xsl:template>
<xsl:template match="@*" mode="addAttributes">
<xsl:copy/>
</xsl:template>
<xsl:template match="sch:name">
<xsl:choose>
<xsl:when test="@zvon:fullPath='yes'">
<aaa:apply-templates select="." mode="fullPath"/>
</xsl:when>
<xsl:otherwise><aaa:value-of select="name([EMAIL PROTECTED])"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="sch:schema">
<aaa:template match="{$docRoot}">
<xsl:call-template name="documentWrapper"/>
<xsl:call-template name="schemaDiagnosticWrapper"/>
</aaa:template>
<xsl:apply-templates select="sch:pattern/sch:rule"/>
</xsl:template>
<xsl:template match="sch:schema" mode="process">
<xsl:apply-templates select="sch:p | sch:pattern[$phase='#ALL'] |
sch:pattern[key('PHASE',@id)/@id = $phase]"/>
</xsl:template>
<xsl:template match="sch:schema" mode="diagnostic">
<xsl:apply-templates select="sch:diagnostics/sch:diagnostic"/>
<xsl:apply-templates select="sch:pattern" mode="diagnostics"/>
</xsl:template>
<xsl:template match="sch:pattern" mode="diagnostics">
<xsl:for-each
select="sch:rule[sch:report/@diagnostics|sch:assert/@diagnostics]">
<aaa:template match="[EMAIL PROTECTED]"
mode="dia_{generate-id(parent::sch:pattern)}" priority="10">
<xsl:for-each select="sch:[EMAIL PROTECTED] | sch:[EMAIL PROTECTED]">
<xsl:variable name="startNOT">
<xsl:if test="self::sch:assert">not(</xsl:if>
</xsl:variable>
<xsl:variable name="endNOT">
<xsl:if test="self::sch:assert">)</xsl:if>
</xsl:variable>
<aaa:if test="[EMAIL PROTECTED]">
<xsl:call-template name='outputDiagnosticAssertReportWrapper'/>
</aaa:if>
</xsl:for-each>
</aaa:template>
</xsl:for-each>
</xsl:template>
<xsl:template name="diagnosticItems">
<xsl:param name="value"/>
<xsl:variable name="start" select="substring-before($value,' ')"/>
<xsl:choose>
<xsl:when test="$start=''">
<aaa:call-template name="diagnostic_{$value}"/>
</xsl:when>
<xsl:otherwise>
<aaa:call-template name="diagnostic_{$start}"/>
<xsl:call-template name="diagnosticItems">
<xsl:with-param name="value" select="substring-after($value,' ')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="sch:diagnostic">
<aaa:template name="[EMAIL PROTECTED]">
<xsl:call-template name="diagnosticWrapper"/>
</aaa:template>
</xsl:template>
<xsl:template match="sch:value-of">
<aaa:value-of select="[EMAIL PROTECTED]"/>
</xsl:template>
<xsl:template match="*"/>
<xsl:template name='applyRules'>
<aaa:apply-templates select="{$docRoot}" mode="{generate-id(.)}"/>
</xsl:template>
<xsl:template match="/">
<aaa:stylesheet version="1.0" >
<xsl:for-each select="/sch:schema/namespace::*">
<xsl:variable name="prefix" select="name()"/>
<xsl:if test="not($prefix='xml' or $prefix='')">
<xsl:attribute name="{$prefix}:{$prefix}" namespace="{.}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="/sch:schema/sch:ns">
<xsl:if test="not(@prefix='xml' or @prefix='')">
<xsl:attribute name="[EMAIL PROTECTED]:[EMAIL PROTECTED]"
namespace="[EMAIL PROTECTED]">
<xsl:value-of select="@uri"/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<aaa:output method="{$outputMethod}" indent="yes"/>
<xsl:apply-templates select="/sch:schema/sch:key" mode="defineKey"/>
<xsl:apply-templates select="sch:schema"/>
<xsl:for-each select="/sch:schema/sch:pattern">
<aaa:template match="text()" mode="{generate-id()}"/>
<aaa:template match="*|@*" mode="{generate-id()}">
<aaa:apply-templates select="node()|@*" mode="{generate-id()}"/>
</aaa:template>
<aaa:template match="text()" mode="dia_{generate-id()}"/>
<aaa:template match="*|@*" mode="dia_{generate-id()}">
<aaa:apply-templates select="node()|@*" mode="dia_{generate-id()}"/>
</aaa:template>
</xsl:for-each>
<aaa:template match="{$docRoot}" mode="startDiagnostics">
<xsl:for-each select="/sch:schema/sch:pattern">
<aaa:apply-templates select="{$docRoot}" mode="dia_{generate-id(.)}"/>
</xsl:for-each>
</aaa:template>
<xsl:apply-templates select="sch:schema" mode="diagnostic"/>
<xsl:call-template name="fullPath"/>
</aaa:stylesheet>
</xsl:template>
<xsl:template match="sch:dir">
<xsl:call-template name="dirWrapper"/>
</xsl:template>
<xsl:template match="sch:span">
<xsl:call-template name="spanWrapper"/>
</xsl:template>
<xsl:template match="sch:p">
<xsl:call-template name="pWrapper"/>
</xsl:template>
<xsl:template match="@icon">
<xsl:call-template name="iconWrapper"/>
</xsl:template>
<xsl:template match="sch:emph">
<xsl:call-template name="emphWrapper"/>
</xsl:template>
<xsl:template match="sch:title">
<xsl:apply-templates/>
</xsl:template>
<xsl:param name="phase">
<xsl:choose>
<xsl:when test="/sch:schema/@defaultPhase">
<xsl:value-of select="/sch:schema/@defaultPhase"/>
</xsl:when>
<xsl:otherwise>#ALL</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:template match="sch:active">
<xsl:apply-templates select="text() | sch:dir | sch:span | sch:emph"/>
</xsl:template>
</xsl:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform-wrappers.xsl
Index: xmlform-wrappers.xsl
===================================================================
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sch="http://www.ascc.net/xml/schematron"
xmlns:aaa="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:zvon="http://zvon.org/schematron"
>
<!-- root of an XML Form document -->
<xsl:variable name="docRootPrefix">/xmlform/instance/</xsl:variable>
<xsl:template name="documentWrapper">
<xmlform xmlns:xform="http://xml.apache.cocoon/xmlform">
<instance>
<aaa:copy-of select="."/>
</instance>
<validationResult>
<xsl:apply-templates select="." mode="process"/>
</validationResult>
</xmlform>
</xsl:template>
<xsl:template name="schemaTitleWrapper">
<xsl:if test="sch:title">
<h2>
<xsl:apply-templates select="sch:title"/>
</h2>
</xsl:if>
</xsl:template>
<xsl:template name="patternWrapper">
<pattern name="[EMAIL PROTECTED]">
<xsl:call-template name="applyRules"/>
</pattern>
</xsl:template>
<xsl:template name="reportAssertWrapper">
<error>
<path>
<aaa:variable name="fpath">
<aaa:apply-templates select="." mode="fullPath"/>
</aaa:variable>
<aaa:value-of select="substring-after($fpath, '{$docRootPrefix}')"/>
</path>
<message>
<xsl:apply-templates/>
</message>
</error>
</xsl:template>
<xsl:template name="patternTitleWrapper">
<tr>
<th class="pattern">
<a name="[EMAIL PROTECTED]"> </a>
<xsl:text>Pattern: </xsl:text>
<span class="patternTitle"><xsl:value-of select="@name"/></span>
</th>
</tr>
</xsl:template>
<xsl:template name="patternSeeWrapper">
<xsl:if test="@see">
<tr>
<td>
<xsl:text>Documentation: </xsl:text>
<a href="[EMAIL PROTECTED]"> see here </a>
</td>
</tr>
</xsl:if>
</xsl:template>
<xsl:template name="pWrapper">
<div>
<xsl:copy-of select="@class|@id"/>
<xsl:apply-templates select="@icon"/>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template name="iconWrapper">
<img src="{.}"/>
</xsl:template>
<xsl:template name="emphWrapper">
<em><xsl:apply-templates/></em>
</xsl:template>
<xsl:template name="spanWrapper">
<span>
<xsl:copy-of select="@class"/>
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template name="dirWrapper">
<span dir="[EMAIL PROTECTED]">
<xsl:apply-templates/>
</span>
</xsl:template>
<xsl:template name="zvonDiagnostics-URI">
</xsl:template>
<xsl:template name="schemaDiagnosticWrapper">
<xsl:choose>
<xsl:when test="parent::*/@zvon:diagnostics-URI">
<aaa:apply-templates select="/" mode="startDiagnostics"/>
</xsl:when>
<xsl:otherwise>
<aaa:message>
<aaa:apply-templates select="/" mode="startDiagnostics"/>
</aaa:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="outputDiagnosticAssertReportWrapper">
<xsl:choose>
<xsl:when test="@zvon:diagnostics-URI">
<xsl:call-template name="diagnosticItems">
<xsl:with-param name="value"
select="normalize-space(@diagnostics)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="diagnosticItems">
<xsl:with-param name="value" select="normalize-space(@diagnostics)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="diagnosticWrapper">
<xsl:text>
Diagnostics:
</xsl:text>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xmlform.bat
Index: xmlform.bat
===================================================================
call xslt xmlform-sch-report.xml xmlform-schematron.xsl xmlform-sch-report.xsl
call xslt some-xmlform.xml xmlform-sch-report.xsl result.xml
1.1
xml-cocoon2/src/scratchpad/webapp/mount/xmlform/schematron/xslt.bat
Index: xslt.bat
===================================================================
set JAVA_HOME=c:\devtools\jdk1.3
set
CLASSPATH=C:\ivo\CocoonForm\lib\xml-apis.jar;C:\ivo\CocoonForm\lib\xerces-1.4.4.jar;C:\ivo\CocoonForm\lib\xalan.jar
%JAVA_HOME%\bin\java org.apache.xalan.xslt.Process -IN %1 -XSL %2 -OUT %3
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]