You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2024/08/08 06:59:03 UTC
(xalan-java) branch xalan-j_xslt3.0 updated: committing implementation of attributes xsl:type/xsl:validation on literal result elements (jira issue XALANJ-2771), along with few conformance tests
This is an automated email from the ASF dual-hosted git repository.
mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git
The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
new 2f974723a committing implementation of attributes xsl:type/xsl:validation on literal result elements (jira issue XALANJ-2771), along with few conformance tests
2f974723a is described below
commit 2f974723a6edfac0309e1c4b517befd28579e77d
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu Aug 8 12:28:52 2024 +0530
committing implementation of attributes xsl:type/xsl:validation on literal result elements (jira issue XALANJ-2771), along with few conformance tests
---
src/org/apache/xalan/processor/ProcessorLRE.java | 40 ++++
src/org/apache/xalan/processor/XSLTSchema.java | 12 +-
src/org/apache/xalan/templates/ElemElement.java | 252 +--------------------
.../apache/xalan/templates/ElemLiteralResult.java | 134 ++++++++++-
src/org/apache/xalan/templates/ElemUse.java | 240 ++++++++++++++++++++
.../xslt/util/XslTransformEvaluationHelper.java | 36 ++-
src/org/apache/xpath/operations/InstanceOf.java | 3 +-
tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java | 3 +-
.../xalan/xslt3/XslElementValidationTests.java | 4 +-
...=> XslLiteralResultElementValidationTests.java} | 38 ++--
.../gold/test1.out | 7 +
.../gold/test2.out | 22 ++
.../gold/test3.out | 22 ++
.../info_2.xsd | 35 +++
.../test1.xml | 8 +
.../test1.xsl | 44 ++++
.../test2.xsl | 80 +++++++
.../test3.xsl | 47 ++++
18 files changed, 740 insertions(+), 287 deletions(-)
diff --git a/src/org/apache/xalan/processor/ProcessorLRE.java b/src/org/apache/xalan/processor/ProcessorLRE.java
index 67a20bbc4..907d8106e 100644
--- a/src/org/apache/xalan/processor/ProcessorLRE.java
+++ b/src/org/apache/xalan/processor/ProcessorLRE.java
@@ -35,6 +35,7 @@ import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.StylesheetRoot;
import org.apache.xalan.templates.XMLNSDecl;
+import org.apache.xml.utils.QName;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xpath.XPath;
import org.xml.sax.Attributes;
@@ -301,6 +302,12 @@ public class ProcessorLRE extends ProcessorTemplateElem
setPropertiesFromAttributes(handler, rawName, attributes, elem);
}
}
+
+ if (elem instanceof ElemLiteralResult) {
+ // Store any available literal result element attributes
+ // xsl:type and xsl:validation.
+ storeXslTypeValidationValue((ElemLiteralResult)elem, attributes);
+ }
appendAndPush(handler, elem);
}
@@ -365,4 +372,37 @@ public class ProcessorLRE extends ProcessorTemplateElem
}
return false;
}
+
+ /**
+ * This method stores the values of attributes xsl:type and xsl:validation, available
+ * on XSL stylesheet's literal result element.
+ */
+ private void storeXslTypeValidationValue(ElemLiteralResult elem, Attributes attributes) {
+
+ int n = attributes.getLength();
+ for (int i = 0; i < n; i++)
+ {
+ String localName = attributes.getLocalName(i);
+ String uri = attributes.getURI(i);
+ if (Constants.S_XSLNAMESPACEURL.equals(uri) && "type".equals(localName)) {
+ String attrValue = attributes.getValue(i);
+ QName typeQName = null;
+ if (attrValue.contains(":")) {
+ String typePrefix = attrValue.substring(0, attrValue.indexOf(':'));
+ String typeLocalName = attrValue.substring(attrValue.indexOf(':') + 1);
+ typeQName = new QName(null, typePrefix, typeLocalName);
+ }
+ else {
+ typeQName = new QName(null, null, attrValue);
+ }
+ // The type's namespace will be determined within the class
+ // object ElemLiteralResult.
+ elem.setType(typeQName);
+ }
+ else if (Constants.S_XSLNAMESPACEURL.equals(uri) && "validation".equals(localName)) {
+ String attrValue = attributes.getValue(i);
+ elem.setValidation(attrValue);
+ }
+ }
+ }
}
diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index ca570497c..3ed6a6361 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -392,7 +392,13 @@ public class XSLTSchema extends XSLTElementDef
XSLTAttributeDef.T_QNAMES, false, false,XSLTAttributeDef.ERROR);
XSLTAttributeDef xslVersionAttr =
new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "version",
- XSLTAttributeDef.T_NMTOKEN, false, false,XSLTAttributeDef.ERROR);
+ XSLTAttributeDef.T_NMTOKEN, false, false,XSLTAttributeDef.ERROR);
+ XSLTAttributeDef xslTypeAttrOpt =
+ new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "type",
+ XSLTAttributeDef.T_QNAME, false, false, XSLTAttributeDef.ERROR);
+ XSLTAttributeDef xslValidationAttrOpt =
+ new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "validation",
+ XSLTAttributeDef.T_QNAME, false, false, XSLTAttributeDef.ERROR);
XSLTElementDef charData = new XSLTElementDef(this, null, "text()",
null /*alias */, null /* elements */, null, /* attributes */
@@ -432,7 +438,9 @@ public class XSLTSchema extends XSLTElementDef
xslUseAttributeSetsAttr,
xslVersionAttr,
xslResultAttr,
- resultAttr },
+ resultAttr,
+ xslTypeAttrOpt,
+ xslValidationAttrOpt },
new ProcessorLRE(),
ElemLiteralResult.class /* class object */, 20, true);
XSLTElementDef unknownElement =
diff --git a/src/org/apache/xalan/templates/ElemElement.java b/src/org/apache/xalan/templates/ElemElement.java
index 3eda5f2ac..375d56ae1 100644
--- a/src/org/apache/xalan/templates/ElemElement.java
+++ b/src/org/apache/xalan/templates/ElemElement.java
@@ -20,8 +20,6 @@
*/
package org.apache.xalan.templates;
-import java.util.List;
-
import javax.xml.XMLConstants;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
@@ -30,36 +28,22 @@ import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
-import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSModel;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.apache.xml.dtm.DTM;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.XML11Char;
-import org.apache.xpath.Expression;
-import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
-import org.apache.xpath.composite.SequenceTypeSupport;
-import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XRTreeFrag;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
- * Implement xsl:element
- * <pre>
- * <!ELEMENT xsl:element %template;>
- * <!ATTLIST xsl:element
- * name %avt; #REQUIRED
- * namespace %avt; #IMPLIED
- * use-attribute-sets %qnames; #IMPLIED
- * %space-att;
- * >
- * </pre>
- * @see <a href="http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element">XXX in XSLT Specification</a>
+ * Implementation of XSL stylesheet instruction xsl:element.
+ *
+ * @see <a href="https://www.w3.org/TR/xslt-30/#xsl-element">xsl:element in XSLT 3.0 Specification</a>
+ *
* @xsl.usage advanced
*/
public class ElemElement extends ElemUse
@@ -136,48 +120,6 @@ public class ElemElement extends ElemUse
{
return m_namespace_avt;
}
-
- /**
- * An optional attribute "type" may be present on xsl:element
- * instruction. When this attribute is present, an element node
- * created by xsl:element instruction is validated with this type.
- */
- protected QName m_type = null;
-
- /**
- * Get the value of "type" attribute.
- */
- public QName getType() {
- return m_type;
- }
-
- /**
- * Set the value of "type" attribute.
- */
- public void setType(QName type) {
- this.m_type = type;
- }
-
- /**
- * An optional attribute "validation" may be present on xsl:element
- * instruction. When this attribute is present, an element node
- * created by xsl:element instruction is validated with this type.
- */
- protected String m_validation = null;
-
- /**
- * Get the value of "validation" attribute.
- */
- public String getValidation() {
- return m_validation;
- }
-
- /**
- * Set the value of "validation" attribute.
- */
- public void setValidation(String validation) {
- this.m_validation = validation;
- }
/**
* This function is called after everything else has been
@@ -402,7 +344,8 @@ public class ElemElement extends ElemUse
SourceLocator srcLocator = xctxt.getSAXLocator();
if ((m_type != null) && (m_validation != null)) {
- throw new TransformerException("XTTE1540 : An xsl:element instruction cannot have both the attributes 'type' and 'validation'.", srcLocator);
+ throw new TransformerException("XTTE1540 : An xsl:element instruction cannot have both the attributes "
+ + "'type' and 'validation'.", srcLocator);
}
if (m_type != null) {
@@ -495,8 +438,8 @@ public class ElemElement extends ElemUse
// The validation value 'preserve' is presently not implemented.
}
- // After any needed element node validation by xsl:element instruction's "type" or
- // "validation" attribute, emit the element node to XSL
+ // After any needed element node validation by xsl:element instruction's
+ // type/validation attribute, emit the element node to XSL
// transform's output.
transformer.executeChildTemplates(this, shouldAddAttrs);
@@ -534,184 +477,5 @@ public class ElemElement extends ElemUse
super.callChildVisitors(visitor, callAttrs);
}
-
- /**
- * Validate XSL instruction xsl:element's evaluation result, with an XML Schema built-in type,
- * specified by xsl:element's 'type' attribute.
- */
- private void validateXslElementResultWithBuiltInSchemaType(String xmlStr, QName typeQname, XPathContext xctxt) throws TransformerException {
-
- SourceLocator srcLocator = xctxt.getSAXLocator();
-
- xmlStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
- String dataTypeLocalName = typeQname.getLocalName();
- String xpathConstructorFuncExprStr = "xs:" + dataTypeLocalName + "('" + xmlStr + "')";
- ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
- List<XMLNSDecl> prefixTable = null;
- if (elemTemplateElement != null) {
- prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
- }
- String xmlSchemaNsPrefix = XslTransformEvaluationHelper.getXMLSchemaNsPref(prefixTable);
- if (xmlSchemaNsPrefix != null) {
- xpathConstructorFuncExprStr += " instance of " + xmlSchemaNsPrefix + ":" + dataTypeLocalName;
- }
- else {
- xpathConstructorFuncExprStr += " instance of xs:" + dataTypeLocalName;
- }
-
- XPath xpath = new XPath(xpathConstructorFuncExprStr, srcLocator, xctxt.getNamespaceContext(), XPath.SELECT, null);
-
- XObject xObj = null;
- boolean isInstanceOf;
- try {
- xObj = xpath.executeInstanceOf(xctxt, DTM.NULL, null);
- isInstanceOf = ((xObj.bool() == true) ? true : false);
- }
- catch (TransformerException ex) {
- isInstanceOf = false;
- }
-
- if (!isInstanceOf) {
- throw new TransformerException("XTTE1540 : An element node constructed via XSL stylesheet's xsl:element "
- + "instruction, is not valid according to type xs:" + dataTypeLocalName + " "
- + "specified as value of xsl:element's attribute 'type'.", srcLocator);
- }
- }
-
- /**
- * Validate XSL instruction xsl:element's evaluation result, with an XML Schema user-defined type,
- * specified by xsl:element's 'type' attribute.
- */
- private void validateXslElementResultWithUserDefinedSchemaType(String nodeName, TransformerImpl transformer,
- XPathContext xctxt, String xmlStr, XSModel xsModel) throws TransformerException {
- String tempStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
-
- xmlStr = "<" + nodeName + " ";
-
- SourceLocator srcLocator = xctxt.getSAXLocator();
-
- ElemTemplateElement childElem = getFirstChildElem();
- while (childElem != null && childElem instanceof ElemAttribute) {
- ElemAttribute elemAttr = (ElemAttribute)childElem;
- AVT attrAvt = elemAttr.getName();
- String attrName = attrAvt.evaluate(xctxt, xctxt.getContextNode(), xctxt.getNamespaceContext());
- Expression attrSelectExpr = elemAttr.getSelect();
- String attrVal = null;
- if (attrSelectExpr != null) {
- elemAttr.fixupVariables();
- XObject xpathEvalResult = attrSelectExpr.execute(xctxt);
- attrVal = XslTransformEvaluationHelper.getStrVal(xpathEvalResult);
- }
- else {
- attrVal = transformer.transformToString(elemAttr);
- }
- xmlStr = xmlStr + attrName+"=\"" + attrVal + "\" ";
- childElem = childElem.getNextSiblingElem();
- }
-
- xmlStr = xmlStr.trim() + ">" + tempStr + "</" + nodeName + ">";
- xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlStr;
-
- String dataTypeLocalName = m_type.getLocalName();
- String dataTypeNamespace = m_type.getNamespace();
-
- XSTypeDefinition typeDefn = xsModel.getTypeDefinition(dataTypeLocalName, dataTypeNamespace);
-
- if (typeDefn != null) {
- boolean isXmlStrValid;
- String errMesg = null;
- try {
- isXmlStrValid = SequenceTypeSupport.isXmlStrValid(xmlStr, null, typeDefn);
- }
- catch (Exception ex) {
- isXmlStrValid = false;
- errMesg = ex.getMessage();
- }
-
- if (!isXmlStrValid) {
- throw new TransformerException("XTTE1540 : An element node constructed via XSL stylesheet's xsl:element "
- + "instruction, is not valid according to type " + dataTypeLocalName + " "
- + "specified as value of xsl:element's attribute 'type'. " + errMesg, srcLocator);
- }
- }
- }
-
- /**
- * When an XSL instruction xsl:element has "validation" attribute with values 'strict' or 'lax',
- * validate the result of xsl:element instruction evaluation with the corresponding element
- * declaration available in the schema.
- */
- private void validateXslElementResultWithSchemaElemDecl(String nodeName, TransformerImpl transformer,
- XPathContext xctxt,
- XSElementDeclaration elemDecl) throws TransformerException {
-
- int rootNodeHandleOfRtf = transformer.transformToRTF(this);
-
- SourceLocator srcLocator = xctxt.getSAXLocator();
-
- NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();
-
- if (nodeList != null) {
- Node node = nodeList.item(0);
-
- String xmlStr = null;
- try {
- xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
- } catch (Exception ex) {
- throw new TransformerException("XTTE1540 : An error occured while evaluating an XSL stylesheet "
- + "xsl:element instruction.", srcLocator);
- }
-
- String tempStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
-
- xmlStr = "<" + nodeName + " ";
-
- ElemTemplateElement childElem = getFirstChildElem();
- while (childElem != null && childElem instanceof ElemAttribute) {
- ElemAttribute elemAttr = (ElemAttribute)childElem;
- AVT attrAvt = elemAttr.getName();
- String attrName = attrAvt.evaluate(xctxt, xctxt.getContextNode(), xctxt.getNamespaceContext());
- Expression attrSelectExpr = elemAttr.getSelect();
- String attrVal = null;
- if (attrSelectExpr != null) {
- elemAttr.fixupVariables();
- XObject xpathEvalResult = attrSelectExpr.execute(xctxt);
- attrVal = XslTransformEvaluationHelper.getStrVal(xpathEvalResult);
- }
- else {
- attrVal = transformer.transformToString(elemAttr);
- }
- xmlStr = xmlStr + attrName+"=\"" + attrVal + "\" ";
- childElem = childElem.getNextSiblingElem();
- }
-
- xmlStr = xmlStr.trim() + ">" + tempStr + "</" + nodeName + ">";
- xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlStr;
-
- boolean isXmlStrValid;
- String errMesg = null;
- try {
- isXmlStrValid = SequenceTypeSupport.isXmlStrValid(xmlStr, (XSElementDecl)elemDecl, null);
- }
- catch (Exception ex) {
- isXmlStrValid = false;
- errMesg = ex.getMessage();
- }
-
- if (!isXmlStrValid) {
- throw new TransformerException("XTTE1540 : An element node constructed via XSL stylesheet's xsl:element "
- + "instruction, is not valid according to the corresponding "
- + "element declaration available in the schema. " + errMesg, srcLocator);
- }
- }
- }
-
- /**
- * Check for the allowed values of "validation" attribute.
- */
- private boolean isValidationStrOk(String validationStr) {
- return ("strict".equals(validationStr) || "lax".equals(validationStr) ||
- "preserve".equals(validationStr) || "strip".equals(validationStr));
- }
}
diff --git a/src/org/apache/xalan/templates/ElemLiteralResult.java b/src/org/apache/xalan/templates/ElemLiteralResult.java
index 02504e14c..ab4cbf2bd 100644
--- a/src/org/apache/xalan/templates/ElemLiteralResult.java
+++ b/src/org/apache/xalan/templates/ElemLiteralResult.java
@@ -24,15 +24,23 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
+import org.apache.xerces.xs.XSElementDeclaration;
+import org.apache.xerces.xs.XSModel;
import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
import org.apache.xml.utils.StringVector;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
@@ -47,8 +55,10 @@ import org.xml.sax.SAXException;
import xml.xpath31.processor.types.XSAnyType;
/**
- * Implement a Literal Result Element.
- * @see <a href="https://www.w3.org/TR/xslt-30/#literal-result-element">literal-result-element within XSLT 3.0 Specification</a>
+ * Implementation of XSL stylesheet literal result element.
+ *
+ * @see <a href="https://www.w3.org/TR/xslt-30/#literal-result-element">literal-result-element in XSLT 3.0 Specification</a>
+ *
* @xsl.usage advanced
*/
public class ElemLiteralResult extends ElemUse
@@ -1304,6 +1314,10 @@ public class ElemLiteralResult extends ElemUse
throws TransformerException
{
SerializationHandler rhandler = transformer.getSerializationHandler();
+
+ XPathContext xctxt = transformer.getXPathContext();
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
try
{
@@ -1351,7 +1365,6 @@ public class ElemLiteralResult extends ElemUse
for (int i = (nAttrs - 1); i >= 0; i--)
{
AVT avt = (AVT) m_avts.get(i);
- XPathContext xctxt = transformer.getXPathContext();
int sourceNode = xctxt.getCurrentNode();
XObject xpath3ContextItem = xctxt.getXPath3ContextItem();
String avtStr = avt.getSimpleString();
@@ -1387,7 +1400,118 @@ public class ElemLiteralResult extends ElemUse
}
// Now process all the elements in this subtree
- // TODO: Process m_extensionElementPrefixes && m_attributeSetsNames
+
+ // Process xsl:type & xsl:validation attributes, if present
+
+ if ((m_type != null) && (m_validation != null)) {
+ throw new TransformerException("XTTE1540 : A literal result element cannot have both the attributes "
+ + "'xsl:type' and 'xsl:validation'.", srcLocator);
+ }
+
+ String nodeName = getNodeName();
+ String nodeNamespace = getNamespace();
+
+ if (m_type != null) {
+ // A literal result element has an attribute "xsl:type".
+ // An element node constructed needs to be validated
+ // by this type.
+
+ int rootNodeHandleOfRtf = transformer.transformToRTF(this);
+
+ NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();
+
+ if (nodeList != null) {
+ Node node = nodeList.item(0);
+
+ String xmlStr = null;
+ try {
+ xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
+ } catch (Exception ex) {
+ throw new TransformerException("XTTE1540 : An error occured while evaluating an XSL literal result element.", srcLocator);
+ }
+
+ ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
+ List<XMLNSDecl> prefixTable = null;
+ if (elemTemplateElement != null) {
+ prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
+ }
+
+ String typeNsUri = XslTransformEvaluationHelper.getNsUriFromPrefix(m_type.getPrefix(), prefixTable);
+
+ if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNsUri)) {
+ // An element content needs to be validated with an XML Schema built-in type.
+ validateXslElementResultWithBuiltInSchemaType(xmlStr, m_type, xctxt);
+ }
+ else {
+ XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
+
+ if (xsModel != null) {
+ // An XML input document has been validated with a schema.
+ // An element content needs to be validated with an XML Schema
+ // user-defined type.
+ validateXslElementResultWithUserDefinedSchemaType(nodeName, transformer, xctxt, xmlStr, xsModel);
+ }
+ else {
+ throw new TransformerException("XTTE1540 : Validation was requested of an XML node produced by literal "
+ + "result element, but XML input document was not validated with a "
+ + "schema.", srcLocator);
+ }
+ }
+ }
+ }
+ else if (m_validation != null) {
+ // An XSL stylesheet literal result element has an attribute
+ // "validation".
+ // An element node constructed needs to be validated
+ // by an element declaration available in the schema.
+
+ if (!isValidationStrOk(m_validation)) {
+ throw new TransformerException("XTTE1540 : A literal result element's attribute 'xsl:validation' can only have one of following "
+ + "values : strict, lax, preserve, strip.", srcLocator);
+ }
+ else if ("strict".equals(m_validation)) {
+ XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
+ if (xsModel != null) {
+ String nodeLocalName = QName.getLocalPart(nodeName);
+ XSElementDeclaration elemDecl = xsModel.getElementDeclaration(nodeLocalName, nodeNamespace);
+ if (elemDecl != null) {
+ validateXslElementResultWithSchemaElemDecl(nodeName, transformer, xctxt, elemDecl);
+ }
+ else {
+ throw new TransformerException("XTTE1540 : A literal result element's attribute \"validation\" has value 'strict', but "
+ + "the schema available doesn't have a corresponding element "
+ + "declaration.", srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("XTTE1540 : A literal result element's attribute \"validation\" has value 'strict', but "
+ + "an XML input document has not been validated with "
+ + "a schema.", srcLocator);
+ }
+ }
+ else if ("lax".equals(m_validation)) {
+ // An attribute "validation"'s value 'lax' has the same effect as the value strict, except that
+ // whereas strict validation fails if there is no available top-level element declaration in
+ // the schema.
+
+ XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
+ if (xsModel != null) {
+ String nodeLocalName = QName.getLocalPart(nodeName);
+ XSElementDeclaration elemDecl = xsModel.getElementDeclaration(nodeLocalName, nodeNamespace);
+ if (elemDecl != null) {
+ validateXslElementResultWithSchemaElemDecl(nodeName, transformer, xctxt, elemDecl);
+ }
+ }
+ }
+
+ // The validation value 'strip' requires no validation.
+
+ // The validation value 'preserve' is presently not implemented.
+ }
+
+ // After any needed element node validation by literal result element's
+ // xsl:type/xsl:validation attribute, emit the element node to XSL
+ // transform's output.
transformer.executeChildTemplates(this, true);
}
catch (TransformerException te)
@@ -1501,5 +1625,5 @@ public class ElemLiteralResult extends ElemUse
throw new DOMException(code, themsg);
}
-
+
}
diff --git a/src/org/apache/xalan/templates/ElemUse.java b/src/org/apache/xalan/templates/ElemUse.java
index 7b5d2b6e9..c6dddfd59 100644
--- a/src/org/apache/xalan/templates/ElemUse.java
+++ b/src/org/apache/xalan/templates/ElemUse.java
@@ -20,14 +20,31 @@
*/
package org.apache.xalan.templates;
+import java.util.List;
import java.util.Vector;
+import javax.xml.XMLConstants;
+import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xerces.impl.xs.XSElementDecl;
+import org.apache.xerces.xs.XSElementDeclaration;
+import org.apache.xerces.xs.XSModel;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.apache.xml.dtm.DTM;
import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.composite.SequenceTypeSupport;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
* Implement xsl:use.
@@ -46,6 +63,46 @@ public class ElemUse extends ElemTemplateElement
* @serial
*/
private QName m_attributeSetsNames[] = null;
+
+ /**
+ * Class field to store, an attribute xsl:type's value.
+ */
+ protected QName m_type = null;
+
+ /**
+ * Class field to store, an attribute xsl:validation's value.
+ */
+ protected String m_validation = null;
+
+ /**
+ * Set value of an attribute xsl:type's value.
+ */
+ public void setType(QName type)
+ {
+ m_type = type;
+ }
+
+ /**
+ * Get value of an attribute xsl:type's value.
+ */
+ public QName getType() {
+ return m_type;
+ }
+
+ /**
+ * Set value of an attribute xsl:validation's value.
+ */
+ public void setValidation(String validation)
+ {
+ m_validation = validation;
+ }
+
+ /**
+ * Get value of an attribute xsl:validation's value.
+ */
+ public String getValidation() {
+ return m_validation;
+ }
/**
* Set the "use-attribute-sets" attribute.
@@ -202,4 +259,187 @@ public class ElemUse extends ElemTemplateElement
}
}
+
+ /**
+ * Validate an XSL stylesheet's literal result element content with an XML Schema,
+ * built-in type specified by an attribute 'xsl:type'.
+ */
+ protected void validateXslElementResultWithBuiltInSchemaType(String xmlStr, QName typeQname,
+ XPathContext xctxt) throws TransformerException {
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ xmlStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
+ String dataTypeLocalName = typeQname.getLocalName();
+ String xpathConstructorFuncExprStr = "xs:" + dataTypeLocalName + "('" + xmlStr + "')";
+
+ ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
+ List<XMLNSDecl> prefixTable = null;
+ if (elemTemplateElement != null) {
+ prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
+ }
+ String xmlSchemaNsPrefix = XslTransformEvaluationHelper.getPrefixFromNsUri(XMLConstants.
+ W3C_XML_SCHEMA_NS_URI, prefixTable);
+ if (xmlSchemaNsPrefix != null) {
+ xpathConstructorFuncExprStr += " instance of " + xmlSchemaNsPrefix + ":" + dataTypeLocalName;
+ }
+ else {
+ xpathConstructorFuncExprStr += " instance of xs:" + dataTypeLocalName;
+ }
+
+ XPath xpath = new XPath(xpathConstructorFuncExprStr, srcLocator, xctxt.getNamespaceContext(), XPath.SELECT, null);
+
+ XObject xObj = null;
+ boolean isInstanceOf;
+ try {
+ xObj = xpath.executeInstanceOf(xctxt, DTM.NULL, null);
+ isInstanceOf = ((xObj.bool() == true) ? true : false);
+ }
+ catch (TransformerException ex) {
+ isInstanceOf = false;
+ }
+
+ if (!isInstanceOf) {
+ throw new TransformerException("XTTE1540 : An element node constructed via literal result element,"
+ + " is not valid according to type xs:" + dataTypeLocalName + " "
+ + "specified as value of literal result element's attribute 'xsl:type'.", srcLocator);
+ }
+ }
+
+ /**
+ * Validate an XSL stylesheet's literal result element content with an XML Schema,
+ * user-defined type specified by an attribute 'xsl:type'.
+ */
+ protected void validateXslElementResultWithUserDefinedSchemaType(String nodeName, TransformerImpl transformer,
+ XPathContext xctxt, String xmlStr, XSModel xsModel) throws TransformerException {
+ String tempStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
+
+ xmlStr = "<" + nodeName + " ";
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ ElemTemplateElement childElem = getFirstChildElem();
+ while (childElem != null && childElem instanceof ElemAttribute) {
+ ElemAttribute elemAttr = (ElemAttribute)childElem;
+ AVT attrAvt = elemAttr.getName();
+ String attrName = attrAvt.evaluate(xctxt, xctxt.getContextNode(), xctxt.getNamespaceContext());
+ Expression attrSelectExpr = elemAttr.getSelect();
+ String attrVal = null;
+ if (attrSelectExpr != null) {
+ elemAttr.fixupVariables();
+ XObject xpathEvalResult = attrSelectExpr.execute(xctxt);
+ attrVal = XslTransformEvaluationHelper.getStrVal(xpathEvalResult);
+ }
+ else {
+ attrVal = transformer.transformToString(elemAttr);
+ }
+ xmlStr = xmlStr + attrName+"=\"" + attrVal + "\" ";
+ childElem = childElem.getNextSiblingElem();
+ }
+
+ xmlStr = xmlStr.trim() + ">" + tempStr + "</" + nodeName + ">";
+ xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlStr;
+
+ String dataTypeLocalName = m_type.getLocalName();
+ String dataTypeNamespace = m_type.getNamespace();
+
+ XSTypeDefinition typeDefn = xsModel.getTypeDefinition(dataTypeLocalName, dataTypeNamespace);
+
+ if (typeDefn != null) {
+ boolean isXmlStrValid;
+ String errMesg = null;
+ try {
+ isXmlStrValid = SequenceTypeSupport.isXmlStrValid(xmlStr, null, typeDefn);
+ }
+ catch (Exception ex) {
+ isXmlStrValid = false;
+ errMesg = ex.getMessage();
+ }
+
+ if (!isXmlStrValid) {
+ throw new TransformerException("XTTE1540 : An element node constructed via literal result element,"
+ + " is not valid according to type " + dataTypeLocalName + " "
+ + "specified as value of literal result element's attribute 'xsl:type'. "
+ + "" + errMesg, srcLocator);
+ }
+ }
+ }
+
+ /**
+ * When an XSL literal result element has "xsl:validation" attribute with values
+ * 'strict' or 'lax', validate an element node produced by literal result element's
+ * evaluation with the corresponding element declaration available in the schema.
+ */
+ protected void validateXslElementResultWithSchemaElemDecl(String nodeName, TransformerImpl transformer,
+ XPathContext xctxt,
+ XSElementDeclaration elemDecl) throws TransformerException {
+
+ int rootNodeHandleOfRtf = transformer.transformToRTF(this);
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ NodeList nodeList = (new XRTreeFrag(rootNodeHandleOfRtf, xctxt, this)).convertToNodeset();
+
+ if (nodeList != null) {
+ Node node = nodeList.item(0);
+
+ String xmlStr = null;
+ try {
+ xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
+ } catch (Exception ex) {
+ throw new TransformerException("XTTE1540 : An error occured while evaluating an XSL stylesheet "
+ + "literal result element.", srcLocator);
+ }
+
+ String tempStr = xmlStr.replaceFirst("<\\?.*\\?>", "");
+
+ xmlStr = "<" + nodeName + " ";
+
+ ElemTemplateElement childElem = getFirstChildElem();
+ while (childElem != null && childElem instanceof ElemAttribute) {
+ ElemAttribute elemAttr = (ElemAttribute)childElem;
+ AVT attrAvt = elemAttr.getName();
+ String attrName = attrAvt.evaluate(xctxt, xctxt.getContextNode(), xctxt.getNamespaceContext());
+ Expression attrSelectExpr = elemAttr.getSelect();
+ String attrVal = null;
+ if (attrSelectExpr != null) {
+ elemAttr.fixupVariables();
+ XObject xpathEvalResult = attrSelectExpr.execute(xctxt);
+ attrVal = XslTransformEvaluationHelper.getStrVal(xpathEvalResult);
+ }
+ else {
+ attrVal = transformer.transformToString(elemAttr);
+ }
+ xmlStr = xmlStr + attrName+"=\"" + attrVal + "\" ";
+ childElem = childElem.getNextSiblingElem();
+ }
+
+ xmlStr = xmlStr.trim() + ">" + tempStr + "</" + nodeName + ">";
+ xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlStr;
+
+ boolean isXmlStrValid;
+ String errMesg = null;
+ try {
+ isXmlStrValid = SequenceTypeSupport.isXmlStrValid(xmlStr, (XSElementDecl)elemDecl, null);
+ }
+ catch (Exception ex) {
+ isXmlStrValid = false;
+ errMesg = ex.getMessage();
+ }
+
+ if (!isXmlStrValid) {
+ throw new TransformerException("XTTE1540 : An element node constructed via XSL stylesheet's literal "
+ + "result element, is not valid according to the corresponding "
+ + "element declaration available in the schema. " + errMesg, srcLocator);
+ }
+ }
+ }
+
+ /**
+ * Check for the allowed values of "validation" attribute.
+ */
+ protected boolean isValidationStrOk(String validationStr) {
+ return ("strict".equals(validationStr) || "lax".equals(validationStr) ||
+ "preserve".equals(validationStr) || "strip".equals(validationStr));
+ }
}
diff --git a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
index a0eb5490e..85ac888a2 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformEvaluationHelper.java
@@ -24,7 +24,6 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.XMLConstants;
import javax.xml.transform.TransformerException;
import org.apache.xalan.templates.XMLNSDecl;
@@ -111,22 +110,43 @@ public class XslTransformEvaluationHelper {
}
/**
- * Get the XML Schema namespace prefix used within an XSL stylesheet.
+ * Get prefix from namespace uri, declared within XSL transformation context.
*/
- public static String getXMLSchemaNsPref(List<XMLNSDecl> nsPrefixTable) {
+ public static String getPrefixFromNsUri(String nsUri, List<XMLNSDecl> nsPrefixTable) {
String xmlSchemaNsPrefix = null;
- for (int idx = 0; idx < nsPrefixTable.size(); idx++) {
- XMLNSDecl xmlNSDecl = nsPrefixTable.get(idx);
- if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(xmlNSDecl.getURI())) {
- xmlSchemaNsPrefix= xmlNSDecl.getPrefix();
- break;
+ if (nsUri != null) {
+ for (int idx = 0; idx < nsPrefixTable.size(); idx++) {
+ XMLNSDecl xmlNSDecl = nsPrefixTable.get(idx);
+ if (nsUri.equals(xmlNSDecl.getURI())) {
+ xmlSchemaNsPrefix = xmlNSDecl.getPrefix();
+ break;
+ }
}
}
return xmlSchemaNsPrefix;
}
+ /**
+ * Get namespace uri from prefix, declared within XSL transformation context.
+ */
+ public static String getNsUriFromPrefix(String prefix, List<XMLNSDecl> nsPrefixTable) {
+ String nsUri = null;
+
+ if (prefix != null) {
+ for (int idx = 0; idx < nsPrefixTable.size(); idx++) {
+ XMLNSDecl xmlNSDecl = nsPrefixTable.get(idx);
+ if (prefix.equals(xmlNSDecl.getPrefix())) {
+ nsUri = xmlNSDecl.getURI();
+ break;
+ }
+ }
+ }
+
+ return nsUri;
+ }
+
/**
* Given an XObject object reference, return the string value
* of the object.
diff --git a/src/org/apache/xpath/operations/InstanceOf.java b/src/org/apache/xpath/operations/InstanceOf.java
index 246c16c7e..328542f4b 100644
--- a/src/org/apache/xpath/operations/InstanceOf.java
+++ b/src/org/apache/xpath/operations/InstanceOf.java
@@ -410,7 +410,8 @@ public class InstanceOf extends Operation
if (elemTemplateElement != null) {
prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
}
- java.lang.String xmlSchemaNsPrefix = XslTransformEvaluationHelper.getXMLSchemaNsPref(prefixTable);
+ java.lang.String xmlSchemaNsPrefix = XslTransformEvaluationHelper.getPrefixFromNsUri(XMLConstants.
+ W3C_XML_SCHEMA_NS_URI, prefixTable);
java.lang.String xpathConstructorFuncExprStr = null;
if (xmlSchemaNsPrefix != null) {
diff --git a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
index 8874076cc..898161701 100644
--- a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
@@ -83,7 +83,8 @@ import org.junit.runners.Suite.SuiteClasses;
FnXmlToJsonTests.class, FnAnalyzeStringTests.class, XPathMapOtherTests.class,
JiraIssuesTests.class, XPathNamedFunctionReferenceTests.class, FnApplyTests.class,
XPathGeneralComparisonOpTests.class, FnMapFindTests.class, XPathNumericArithmeticTests.class,
- XslTunnelParameterTests.class, FuncBooleanValuesTests.class, XslElementValidationTests.class })
+ XslTunnelParameterTests.class, FuncBooleanValuesTests.class, XslElementValidationTests.class,
+ XslLiteralResultElementValidationTests.class })
public class Xsl3TestSuite1 {
}
diff --git a/tests/org/apache/xalan/xslt3/XslElementValidationTests.java b/tests/org/apache/xalan/xslt3/XslElementValidationTests.java
index 353a97a34..0142f896b 100644
--- a/tests/org/apache/xalan/xslt3/XslElementValidationTests.java
+++ b/tests/org/apache/xalan/xslt3/XslElementValidationTests.java
@@ -23,8 +23,8 @@ import org.junit.BeforeClass;
import org.junit.Test;
/**
- * XSLT tests cases to test, use of 'type' attribute on XSL stylesheet
- * element xsl:element.
+ * XSLT tests cases to test, use of an attribute type/validation on XSL
+ * instruction xsl:element.
*
* @author Mukul Gandhi <mu...@apache.org>
*
diff --git a/tests/org/apache/xalan/xslt3/XslElementValidationTests.java b/tests/org/apache/xalan/xslt3/XslLiteralResultElementValidationTests.java
similarity index 73%
copy from tests/org/apache/xalan/xslt3/XslElementValidationTests.java
copy to tests/org/apache/xalan/xslt3/XslLiteralResultElementValidationTests.java
index 353a97a34..6d91942fb 100644
--- a/tests/org/apache/xalan/xslt3/XslElementValidationTests.java
+++ b/tests/org/apache/xalan/xslt3/XslLiteralResultElementValidationTests.java
@@ -23,18 +23,20 @@ import org.junit.BeforeClass;
import org.junit.Test;
/**
- * XSLT tests cases to test, use of 'type' attribute on XSL stylesheet
- * element xsl:element.
+ * XSLT tests cases to test, use of an attribute xsl:type/xsl:validation on XSL
+ * literal result element.
*
* @author Mukul Gandhi <mu...@apache.org>
*
* @xsl.usage advanced
*/
-public class XslElementValidationTests extends XSLTransformTestsUtil {
+public class XslLiteralResultElementValidationTests extends XSLTransformTestsUtil {
- private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "xsl_element_validation/";
+ private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX +
+ "xsl_literal_result_element_validation/";
- private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "xsl_element_validation/gold/";
+ private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX +
+ "xsl_literal_result_element_validation/gold/";
@BeforeClass
@@ -50,33 +52,21 @@ public class XslElementValidationTests extends XSLTransformTestsUtil {
}
@Test
- public void xslElementValidationTest1() {
+ public void xslLiteralResultElementValidationTest1() {
String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
- String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";
-
- setXmlValidationProperty(true);
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
@Test
- public void xslElementValidationTest2() {
+ public void xslLiteralResultElementValidationTest2() {
String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
- String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";
-
- runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
- }
-
- @Test
- public void xslElementValidationTest3() {
- String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
- String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
-
- String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";
setXmlValidationProperty(true);
@@ -84,11 +74,11 @@ public class XslElementValidationTests extends XSLTransformTestsUtil {
}
@Test
- public void xslElementValidationTest4() {
+ public void xslLiteralResultElementValidationTest3() {
String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
- String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
- String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
setXmlValidationProperty(true);
diff --git a/tests/xsl_literal_result_element_validation/gold/test1.out b/tests/xsl_literal_result_element_validation/gold/test1.out
new file mode 100644
index 000000000..73280908d
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/gold/test1.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><info>
+ <p>2007-10-11</p>
+ <p>2007-10-12</p>
+ <p>2007-10-13</p>
+ <p>2007-10-14</p>
+ <p>2007-10-15</p>
+</info>
diff --git a/tests/xsl_literal_result_element_validation/gold/test2.out b/tests/xsl_literal_result_element_validation/gold/test2.out
new file mode 100644
index 000000000..65f3b4e76
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/gold/test2.out
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><info>
+ <p t1="hello" t2="there">
+ <val>11</val>
+ <data>a1</data>
+ </p>
+ <p t1="hello" t2="there">
+ <val>12</val>
+ <data>a2</data>
+ </p>
+ <p t1="hello" t2="there">
+ <val>13</val>
+ <data>a3</data>
+ </p>
+ <p t1="hello" t2="there">
+ <val>14</val>
+ <data>a4</data>
+ </p>
+ <p t1="hello" t2="there">
+ <val>15</val>
+ <data>a5</data>
+ </p>
+</info>
diff --git a/tests/xsl_literal_result_element_validation/gold/test3.out b/tests/xsl_literal_result_element_validation/gold/test3.out
new file mode 100644
index 000000000..413aede19
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/gold/test3.out
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><info>
+ <p>
+ <val>11</val>
+ <data>a1</data>
+ </p>
+ <p>
+ <val>12</val>
+ <data>a2</data>
+ </p>
+ <p>
+ <val>13</val>
+ <data>a3</data>
+ </p>
+ <p>
+ <val>14</val>
+ <data>a4</data>
+ </p>
+ <p>
+ <val>15</val>
+ <data>a5</data>
+ </p>
+</info>
diff --git a/tests/xsl_literal_result_element_validation/info_2.xsd b/tests/xsl_literal_result_element_validation/info_2.xsd
new file mode 100644
index 000000000..b81a1960e
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/info_2.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="info" type="Type1"/>
+
+ <xs:complexType name="Type1">
+ <xs:sequence>
+ <xs:element name="a" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="val" type="xs:integer"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="p">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="val">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="10"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="data" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
diff --git a/tests/xsl_literal_result_element_validation/test1.xml b/tests/xsl_literal_result_element_validation/test1.xml
new file mode 100644
index 000000000..6fa79bee2
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/test1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<info>
+ <a val="1">a1</a>
+ <a val="2">a2</a>
+ <a val="3">a3</a>
+ <a val="4">a4</a>
+ <a val="5">a5</a>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_literal_result_element_validation/test1.xsl b/tests/xsl_literal_result_element_validation/test1.xsl
new file mode 100644
index 000000000..4b72ec6e7
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/test1.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1.xml -->
+
+ <!-- An XSLT stylesheet test case, to test validation of literal result
+ element via xsl:type attribute. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/info">
+ <info>
+ <xsl:for-each select="a">
+ <p xsl:type="xs:date">
+ <xsl:sequence select="xs:date('2007-10-10') + xs:dayTimeDuration('P' || @val || 'D')"/>
+ </p>
+ </xsl:for-each>
+ </info>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_literal_result_element_validation/test2.xsl b/tests/xsl_literal_result_element_validation/test2.xsl
new file mode 100644
index 000000000..91e0ac811
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/test2.xsl
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1.xml -->
+
+ <!-- An XSLT stylesheet test case, to test validation of literal result
+ element via xsl:type attribute. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="info" type="Type1"/>
+
+ <xs:complexType name="Type1">
+ <xs:sequence>
+ <xs:element name="a" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="val" type="xs:integer"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="pType">
+ <xs:sequence>
+ <xs:element name="val">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="10"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="data" type="xs:string"/>
+ </xs:sequence>
+ <xs:attribute name="t1" type="xs:string"/>
+ <xs:attribute name="t2" type="xs:string"/>
+ </xs:complexType>
+ </xs:schema>
+ </xsl:import-schema>
+
+ <xsl:template match="/info">
+ <info>
+ <xsl:for-each select="a">
+ <p xsl:type="pType">
+ <xsl:attribute name="t1">hello</xsl:attribute>
+ <xsl:attribute name="t2">there</xsl:attribute>
+ <val><xsl:value-of select="@val + 10"/></val>
+ <data><xsl:value-of select="."/></data>
+ </p>
+ </xsl:for-each>
+ </info>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_literal_result_element_validation/test3.xsl b/tests/xsl_literal_result_element_validation/test3.xsl
new file mode 100644
index 000000000..12d393bf4
--- /dev/null
+++ b/tests/xsl_literal_result_element_validation/test3.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1.xml -->
+
+ <!-- An XSLT stylesheet test case, to test validation of literal result
+ element via xsl:validation attribute. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_2.xsd"/>
+
+ <xsl:template match="/info">
+ <info>
+ <xsl:for-each select="a">
+ <p xsl:validation="strict">
+ <val><xsl:value-of select="@val + 10"/></val>
+ <data><xsl:value-of select="."/></data>
+ </p>
+ </xsl:for-each>
+ </info>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org