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/19 16:31:56 UTC
(xalan-java) branch xalan-j_xslt3.0 updated: committing implementation of xsl:copy-of instruction's attributes 'type' and 'validation', 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 4317a1ace committing implementation of xsl:copy-of instruction's attributes 'type' and 'validation', along with few conformance tests
4317a1ace is described below
commit 4317a1ace9d05f7b8ca15d25e8df2023be68836f
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Aug 19 22:01:43 2024 +0530
committing implementation of xsl:copy-of instruction's attributes 'type' and 'validation', along with few conformance tests
---
src/org/apache/xalan/processor/XSLTSchema.java | 4 +-
src/org/apache/xalan/templates/Constants.java | 6 +-
src/org/apache/xalan/templates/ElemAttribute.java | 25 +-
src/org/apache/xalan/templates/ElemCopyOf.java | 282 +++++++++++++++++-
src/org/apache/xalan/templates/ElemElement.java | 21 +-
.../apache/xalan/templates/ElemLiteralResult.java | 21 +-
.../xalan/templates/ElemTemplateElement.java | 323 ++++++++++++++++++++-
src/org/apache/xalan/templates/ElemUse.java | 302 +------------------
src/org/apache/xalan/templates/StylesheetRoot.java | 2 +-
src/org/apache/xpath/objects/XNodeSet.java | 34 ++-
tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java | 3 +-
.../xalan/xslt3/XslCopyofValidationTests.java | 124 ++++++++
tests/xsl_copyof_validation/gold/test1.out | 27 ++
tests/xsl_copyof_validation/gold/test2.out | 27 ++
tests/xsl_copyof_validation/gold/test3.out | 27 ++
tests/xsl_copyof_validation/gold/test4.out | 27 ++
tests/xsl_copyof_validation/gold/test5.out | 27 ++
tests/xsl_copyof_validation/gold/test6.out | 27 ++
tests/xsl_copyof_validation/info_1.xsd | 52 ++++
tests/xsl_copyof_validation/test1.xml | 8 +
tests/xsl_copyof_validation/test1.xsl | 52 ++++
tests/xsl_copyof_validation/test2.xsl | 52 ++++
tests/xsl_copyof_validation/test3.xsl | 52 ++++
tests/xsl_copyof_validation/test4.xsl | 52 ++++
tests/xsl_copyof_validation/test5.xsl | 53 ++++
tests/xsl_copyof_validation/test6.xsl | 53 ++++
26 files changed, 1331 insertions(+), 352 deletions(-)
diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index ad5ab5378..b1d878573 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -485,7 +485,9 @@ public class XSLTSchema extends XSLTElementDef
XSLTElementDef xslCopyOf = new XSLTElementDef(this,
Constants.S_XSLNAMESPACEURL, "copy-of",
null /*alias */, null /* elements */,
- new XSLTAttributeDef[]{ selectAttrRequired },
+ new XSLTAttributeDef[]{ selectAttrRequired,
+ typeAttrOpt,
+ validationAttrOpt },
new ProcessorTemplateElem(),
ElemCopyOf.class /* class object */, 20, true);
XSLTElementDef xslNumber = new XSLTElementDef(this,
diff --git a/src/org/apache/xalan/templates/Constants.java b/src/org/apache/xalan/templates/Constants.java
index 34991a094..017b82df6 100644
--- a/src/org/apache/xalan/templates/Constants.java
+++ b/src/org/apache/xalan/templates/Constants.java
@@ -197,7 +197,11 @@ public class Constants extends org.apache.xml.utils.Constants
ELEMNAME_FUNCTION_STRING = "function",
ELEMNAME_SEQUENCE_STRING = "sequence",
ELEMNAME_IMPORT_SCHEMA_STRING = "import-schema",
- ELEMNAME_EVALUATE_STRING = "evaluate";
+ ELEMNAME_EVALUATE_STRING = "evaluate",
+ XS_VALIDATION_STRICT_STRING = "strict",
+ XS_VALIDATION_LAX_STRING = "lax",
+ XS_VALIDATION_PRESERVE_STRING = "preserve",
+ XS_VALIDATION_STRIP_STRING = "strip";
/**
* Literals for EXSLT function elements.
diff --git a/src/org/apache/xalan/templates/ElemAttribute.java b/src/org/apache/xalan/templates/ElemAttribute.java
index 898431105..bda4de192 100644
--- a/src/org/apache/xalan/templates/ElemAttribute.java
+++ b/src/org/apache/xalan/templates/ElemAttribute.java
@@ -232,20 +232,23 @@ public class ElemAttribute extends ElemElement
attrVal = transformer.transformToString(this);
}
- if ((m_type != null) && (m_validation != null)) {
+ QName type = getType();
+ String validation = getValidation();
+
+ if ((type != null) && (validation != null)) {
throw new TransformerException("XTTE1540 : An xsl:attribute instruction cannot have both the attributes "
+ "'type' and 'validation'.", srcLocator);
}
- if (m_type != null) {
+ if (type != null) {
// An xsl:attribute instruction has an attribute "type".
// An attribute node constructed needs to be validated
// by this type.
- if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(m_type.getNamespace())) {
+ if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(type.getNamespace())) {
// An attribute value needs to be validated with an XML Schema built-in type.
- validateXslElementAttributeResultWithBuiltInSchemaType(attrVal, m_type, xctxt, ATTRIBUTE);
+ validateXslElementAttributeResultWithBuiltInSchemaType(attrVal, type, xctxt, ATTRIBUTE);
}
else {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
@@ -256,7 +259,7 @@ public class ElemAttribute extends ElemElement
// An attribute value needs to be validated with an XML Schema
// user-defined type.
- XSTypeDefinition typeDefn = xsModel.getTypeDefinition(m_type.getLocalName(), m_type.getNamespace());
+ XSTypeDefinition typeDefn = xsModel.getTypeDefinition(type.getLocalName(), type.getNamespace());
if ((typeDefn != null) && (typeDefn instanceof XSSimpleType)) {
XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)typeDefn;
try {
@@ -264,7 +267,7 @@ public class ElemAttribute extends ElemElement
}
catch (InvalidDatatypeValueException ex) {
throw new TransformerException("XTTE1540 : An attribute value produced by the stylesheet, is not "
- + "valid with the schema type " + m_type.getLocalName() + ".", srcLocator);
+ + "valid with the schema type " + type.getLocalName() + ".", srcLocator);
}
}
else {
@@ -280,17 +283,17 @@ public class ElemAttribute extends ElemElement
}
}
}
- else if (m_validation != null) {
+ else if (validation != null) {
// An xsl:attribute instruction has an attribute "validation".
// An attribute node constructed needs to be validated
// by an attribute declaration available in the schema.
- if (!isValidationStrOk(m_validation)) {
+ if (!isValidationStrOk(validation)) {
throw new TransformerException("XTTE1540 : An xsl:attribute instruction's attribute 'validation' can only have one of following "
+ "values : strict, lax, preserve, strip.", srcLocator);
}
- else if ("strict".equals(m_validation)) {
+ else if ((Constants.XS_VALIDATION_STRICT_STRING).equals(validation)) {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
if (xsModel != null) {
String localName = QName.getLocalPart(nodeName);
@@ -319,7 +322,7 @@ public class ElemAttribute extends ElemElement
+ "a schema.", srcLocator);
}
}
- else if ("lax".equals(m_validation)) {
+ else if ((Constants.XS_VALIDATION_LAX_STRING).equals(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 attribute declaration in
// the schema.
@@ -345,7 +348,7 @@ public class ElemAttribute extends ElemElement
// The validation value 'strip' requires no validation.
- // The validation value 'preserve' is presently not implemented.
+ // The validation value 'preserve' is currently not implemented.
}
try {
diff --git a/src/org/apache/xalan/templates/ElemCopyOf.java b/src/org/apache/xalan/templates/ElemCopyOf.java
index 576cdce74..6e9eea127 100644
--- a/src/org/apache/xalan/templates/ElemCopyOf.java
+++ b/src/org/apache/xalan/templates/ElemCopyOf.java
@@ -30,21 +30,33 @@ import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.serialize.SerializerUtils;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.transformer.TreeWalker2Result;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
+import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
+import org.apache.xerces.impl.dv.XSSimpleType;
+import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
+import org.apache.xerces.impl.xs.XSElementDecl;
+import org.apache.xerces.xs.XSAttributeDeclaration;
+import org.apache.xerces.xs.XSModel;
+import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.ref.DTMTreeWalker;
import org.apache.xml.serializer.SerializationHandler;
+import org.apache.xml.utils.QName;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XPathInlineFunction;
+import org.apache.xpath.composite.SequenceTypeSupport;
import org.apache.xpath.objects.ResultSequence;
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
import org.apache.xpath.objects.XString;
+import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import xml.xpath31.processor.types.XSAnyAtomicType;
@@ -177,13 +189,20 @@ public class ElemCopyOf extends ElemTemplateElement
if (transformer.getDebug())
transformer.getTraceManager().fireTraceEvent(this);
- try
- {
+ try {
XPathContext xctxt = transformer.getXPathContext();
-
+
setXPathContext(xctxt);
-
+
SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ QName type = getType();
+ String validationStr = getValidation();
+
+ if ((type != null) && (validationStr != null)) {
+ throw new TransformerException("XTTE1540 : An xsl:copy-of instruction cannot have both the attributes "
+ + "'type' and 'validation'.", srcLocator);
+ }
int sourceNode = xctxt.getCurrentNode();
@@ -209,8 +228,17 @@ public class ElemCopyOf extends ElemTemplateElement
String strVal = null;
switch (xObjectType) {
- case XObject.CLASS_NODESET :
- copyOfActionOnNodeSet((XNodeSet)value, transformer, handler, xctxt);
+ case XObject.CLASS_NODESET :
+ XNodeSet xNodeSet = (XNodeSet)value;
+ xNodeSet.setTypeAttrForValidation(type);
+ if (validationStr != null) {
+ if (!isValidationStrOk(validationStr)) {
+ throw new TransformerException("XTTE1540 : An xsl:copy-of instruction's attribute 'validation' can only have one of following "
+ + "values : strict, lax, preserve, strip.", srcLocator);
+ }
+ }
+ xNodeSet.setValidationAttrForValidation(validationStr);
+ copyOfActionOnNodeSet(xNodeSet, transformer, handler, xctxt);
break;
case XObject.CLASS_RTREEFRAG :
SerializerUtils.outputResultTreeFragment(
@@ -307,20 +335,30 @@ public class ElemCopyOf extends ElemTemplateElement
DTMIterator dtmIter = nodeSet.iter();
DTMTreeWalker tw = new TreeWalker2Result(transformer, serializationHandler);
- int pos;
+ int pos;
while ((pos = dtmIter.nextNode()) != DTM.NULL) {
DTM dtm = xctxt.getDTMManager().getDTM(pos);
short nodeType = dtm.getNodeType(pos);
if (nodeType == DTM.DOCUMENT_NODE) {
+ // From the 1st XML element node child of document node, validate all
+ // these sibling element nodes if required by XSL stylesheet, and emit
+ // the node to XSL transform's output if validation succeeds.
for (int child = dtm.getFirstChild(pos); child != DTM.NULL;
child = dtm.getNextSibling(child)) {
- tw.traverse(child);
+ validateAndEmitElementNode(nodeSet, xctxt, tw, child, dtm);
}
+ }
+ else if (nodeType == DTM.ELEMENT_NODE) {
+ // Validate an XML element node if required by XSL stylesheet, and emit
+ // the node to XSL transform's output if validation succeeds.
+ validateAndEmitElementNode(nodeSet, xctxt, tw, pos, dtm);
}
else if (nodeType == DTM.ATTRIBUTE_NODE) {
- SerializerUtils.addAttribute(serializationHandler, pos);
+ // Validate an XML attribute node if required by XSL stylesheet, and emit
+ // the node to XSL transform's output if validation succeeds.
+ validateAndEmitAttributeNode(nodeSet, serializationHandler, xctxt, pos, dtm);
}
else {
tw.traverse(pos);
@@ -416,5 +454,229 @@ public class ElemCopyOf extends ElemTemplateElement
return rSeq;
}
+
+ /**
+ * This method does validation of an XML element node with a schema type or
+ * schema element declaration. If an element node is valid with the schema
+ * type or schema element declaration, then the node is emitted to XSL
+ * transformation's output.
+ */
+ private static void validateAndEmitElementNode(XNodeSet nodeSet, XPathContext xctxt,
+ DTMTreeWalker tw, int nodeHandle, DTM dtm) throws TransformerException {
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ try {
+ Node node = dtm.getNode(nodeHandle);
+
+ QName type = nodeSet.getTypeAttrForValidation();
+ String validation = nodeSet.getValidationAttrForValidation();
+
+ if (type != null) {
+ StylesheetRoot stylesheetRoot = XslTransformSharedDatastore.stylesheetRoot;
+ XSModel xsModel = stylesheetRoot.getXsModel();
+ if (xsModel != null) {
+ String xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
+ XSTypeDefinition xsTypeDefn = xsModel.getTypeDefinition(type.getLocalName(), type.getNamespace());
+ if (SequenceTypeSupport.isXmlStrValid(xmlStr, null, xsTypeDefn)) {
+ tw.traverse(nodeHandle);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : xsl:copy-of instruction has 'type' attribute to request "
+ + "validation of xsl:copy-of's result, but an XML input document has not "
+ + "been validated using schema supplied via xsl:import-schema instruction.",
+ srcLocator);
+ }
+ }
+ else if (validation != null) {
+ if ((Constants.XS_VALIDATION_STRICT_STRING).equals(validation)) {
+ StylesheetRoot stylesheetRoot = XslTransformSharedDatastore.stylesheetRoot;
+ XSModel xsModel = stylesheetRoot.getXsModel();
+ if (xsModel != null) {
+ String xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
+ String nodeLocalName = node.getLocalName();
+ String nodeNamespace = node.getNamespaceURI();
+ XSElementDecl schemaElemDecl = (XSElementDecl)(xsModel.getElementDeclaration(nodeLocalName, nodeNamespace));
+ if (schemaElemDecl != null) {
+ if (SequenceTypeSupport.isXmlStrValid(xmlStr, schemaElemDecl, null)) {
+ tw.traverse(nodeHandle);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : xsl:copy-of instruction has 'validation' attribute with value '" +
+ Constants.XS_VALIDATION_STRICT_STRING + "' to request validation of "
+ + "xsl:copy-of's result, but the schema used to validate "
+ + "an XML input document doesn't have global element declaration for "
+ + "an element node produced by xsl:copy-of instruction.", srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : xsl:copy-of instruction has 'validation' attribute to request "
+ + "validation of xsl:copy-of's result, but an XML input "
+ + "document has not been validated using schema supplied "
+ + "via xsl:import-schema instruction.", srcLocator);
+ }
+ }
+ else if ((Constants.XS_VALIDATION_LAX_STRING).equals(validation)) {
+ StylesheetRoot stylesheetRoot = XslTransformSharedDatastore.stylesheetRoot;
+ XSModel xsModel = stylesheetRoot.getXsModel();
+ if (xsModel != null) {
+ String xmlStr = XslTransformEvaluationHelper.serializeXmlDomElementNode(node);
+ String nodeLocalName = node.getLocalName();
+ String nodeNamespace = node.getNamespaceURI();
+ XSElementDecl schemaElemDecl = (XSElementDecl)(xsModel.getElementDeclaration(nodeLocalName, nodeNamespace));
+ if (schemaElemDecl != null) {
+ if (SequenceTypeSupport.isXmlStrValid(xmlStr, schemaElemDecl, null)) {
+ tw.traverse(nodeHandle);
+ }
+ }
+ }
+ }
+
+ // The validation value 'strip' requires no validation.
+
+ // The validation value 'preserve' is currently not implemented.
+ }
+ else {
+ tw.traverse(nodeHandle);
+ }
+ }
+ catch (TransformerException ex) {
+ throw new TransformerException(ex.getMessage(), srcLocator);
+ }
+ catch (Exception ex) {
+ String errMesg = ex.getMessage();
+ throw new TransformerException("XTTE1540 : An error occured while evaluating an XSL stylesheet "
+ + "xsl:copy-of instruction."
+ + ((errMesg != null) ? " " + errMesg : ""), srcLocator);
+ }
+ finally {
+ nodeSet.setTypeAttrForValidation(null);
+ nodeSet.setValidationAttrForValidation(null);
+ }
+ }
+
+ /**
+ * This method does validation of an XML attribute node with a schema type or
+ * schema attribute declaration. If an attribute node is valid with the schema
+ * type or schema attribute declaration, then the node is emitted to XSL
+ * transformation's output.
+ */
+ private static void validateAndEmitAttributeNode(XNodeSet nodeSet, SerializationHandler serializationHandler,
+ XPathContext xctxt, int pos, DTM dtm) throws TransformerException {
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
+ try {
+ Node node = dtm.getNode(pos);
+ String attrLocalName = node.getLocalName();
+ String attrNodeNs = node.getNamespaceURI();
+ String attrStrValue = node.getNodeValue();
+
+ QName type = nodeSet.getTypeAttrForValidation();
+ String validation = nodeSet.getValidationAttrForValidation();
+
+ if (type != null) {
+ StylesheetRoot stylesheetRoot = XslTransformSharedDatastore.stylesheetRoot;
+ XSModel xsModel = stylesheetRoot.getXsModel();
+ if (xsModel != null) {
+ XSTypeDefinition xsTypeDefn = xsModel.getTypeDefinition(type.getLocalName(), type.getNamespace());
+ if (xsTypeDefn != null) {
+ if (xsTypeDefn instanceof XSSimpleType) {
+ XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)xsTypeDefn;
+ try {
+ xsSimpleTypeDecl.validate(attrStrValue, null, null);
+ }
+ catch (InvalidDatatypeValueException ex) {
+ throw new TransformerException("FODC0005 : An attribute '" + attrLocalName + "' that has to be emitted by xsl:copy-of "
+ + "instruction, has a value which is not valid with type '" +
+ type.getLocalName() + "' referred by xsl:copy-of instruction's "
+ + "'type' attribute. " + ex.getMessage(), srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : A xsl:copy-of instruction refers a type '" + type.getLocalName() +
+ "' that is not a schema simpleType, which cannot be used to validate "
+ + "an attribute value.", srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : A xsl:copy-of instruction has 'type' attribute with "
+ + "value '" + type.getLocalName() + "' to request "
+ + "validation of xsl:copy-of's result, but the schema referred via "
+ + "xsl:import-schema instruction does'nt have a global type definition "
+ + "with name '" + type.getLocalName() + "'.", srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : A xsl:copy-of instruction has 'type' attribute to request "
+ + "validation of xsl:copy-of's result, but an XML input document has not "
+ + "been validated using schema supplied via xsl:import-schema instruction.",
+ srcLocator);
+ }
+ }
+ else if (validation != null) {
+ if ((Constants.XS_VALIDATION_STRICT_STRING).equals(validation)) {
+ StylesheetRoot stylesheetRoot = XslTransformSharedDatastore.stylesheetRoot;
+ XSModel xsModel = stylesheetRoot.getXsModel();
+ if (xsModel != null) {
+ XSAttributeDeclaration attrDecl = xsModel.getAttributeDeclaration(attrLocalName, attrNodeNs);
+ if (attrDecl != null) {
+ XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)attrDecl.getTypeDefinition();
+ try {
+ xsSimpleTypeDecl.validate(attrStrValue, null, null);
+ }
+ catch (InvalidDatatypeValueException ex) {
+ throw new TransformerException("FODC0005 : An attribute '" + attrLocalName + "' that has to be emitted by xsl:copy-of "
+ + "instruction, has a value which is not valid with attribute "
+ + "declaration available in the schema." + ex.getMessage(),
+ srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("FODC0005 : An attribute '" + attrLocalName + "' that has to be emitted by xsl:copy-of "
+ + "instruction, doesn't have a corresponding attribute declaration in the "
+ + "schema to validate with. The validation 'strict' has been requested.", srcLocator);
+ }
+ }
+ else {
+ throw new TransformerException("XTTE1540 : An xsl:copy-of instruction's attribute \"validation\" has value 'strict', but "
+ + "an XML input document has not been validated with a schema "
+ + "using xsl:import-schema instruction.", srcLocator);
+ }
+ }
+ else if ((Constants.XS_VALIDATION_LAX_STRING).equals(validation)) {
+ XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
+ if (xsModel != null) {
+ XSAttributeDeclaration attrDecl = xsModel.getAttributeDeclaration(attrLocalName, attrNodeNs);
+ if (attrDecl != null) {
+ XSSimpleTypeDecl xsSimpleTypeDecl = (XSSimpleTypeDecl)attrDecl.getTypeDefinition();
+ try {
+ xsSimpleTypeDecl.validate(attrStrValue, null, null);
+ }
+ catch (InvalidDatatypeValueException ex) {
+ throw new TransformerException("FODC0005 : An attribute '" + attrLocalName + "' that has to be emitted by xsl:copy-of "
+ + "instruction, has a value which is not valid with attribute "
+ + "declaration available in the schema." + ex.getMessage(),
+ srcLocator);
+ }
+ }
+ }
+ }
+
+ // The validation value 'strip' requires no validation.
+
+ // The validation value 'preserve' is currently not implemented.
+ }
+
+ // Emit attribute to XSL transformation's output
+ SerializerUtils.addAttribute(serializationHandler, pos);
+ }
+ finally {
+ nodeSet.setTypeAttrForValidation(null);
+ nodeSet.setValidationAttrForValidation(null);
+ }
+ }
}
diff --git a/src/org/apache/xalan/templates/ElemElement.java b/src/org/apache/xalan/templates/ElemElement.java
index f86549a31..19c36232f 100644
--- a/src/org/apache/xalan/templates/ElemElement.java
+++ b/src/org/apache/xalan/templates/ElemElement.java
@@ -343,12 +343,15 @@ public class ElemElement extends ElemUse
XPathContext xctxt = transformer.getXPathContext();
SourceLocator srcLocator = xctxt.getSAXLocator();
- if ((m_type != null) && (m_validation != null)) {
+ QName type = getType();
+ String validation = getValidation();
+
+ if ((type != null) && (validation != null)) {
throw new TransformerException("XTTE1540 : An xsl:element instruction cannot have both the attributes "
+ "'type' and 'validation'.", srcLocator);
}
- if (m_type != null) {
+ if (type != null) {
// An xsl:element instruction has an attribute "type".
// An element node constructed needs to be validated
@@ -369,9 +372,9 @@ public class ElemElement extends ElemUse
+ "xsl:element instruction.", srcLocator);
}
- if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(m_type.getNamespace())) {
+ if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(type.getNamespace())) {
// An element content needs to be validated with an XML Schema built-in type.
- validateXslElementAttributeResultWithBuiltInSchemaType(xmlStr, m_type, xctxt, XSL_ELEMENT);
+ validateXslElementAttributeResultWithBuiltInSchemaType(xmlStr, type, xctxt, XSL_ELEMENT);
}
else {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
@@ -391,17 +394,17 @@ public class ElemElement extends ElemUse
}
}
}
- else if (m_validation != null) {
+ else if (validation != null) {
// An xsl:element instruction has an attribute "validation".
// An element node constructed needs to be validated
// by an element declaration available in the schema.
- if (!isValidationStrOk(m_validation)) {
+ if (!isValidationStrOk(validation)) {
throw new TransformerException("XTTE1540 : An xsl:element instruction's attribute 'validation' can only have one of following "
+ "values : strict, lax, preserve, strip.", srcLocator);
}
- else if ("strict".equals(m_validation)) {
+ else if ((Constants.XS_VALIDATION_STRICT_STRING).equals(validation)) {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
if (xsModel != null) {
String nodeLocalName = QName.getLocalPart(nodeName);
@@ -421,7 +424,7 @@ public class ElemElement extends ElemUse
+ "a schema.", srcLocator);
}
}
- else if ("lax".equals(m_validation)) {
+ else if ((Constants.XS_VALIDATION_LAX_STRING).equals(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.
@@ -438,7 +441,7 @@ public class ElemElement extends ElemUse
// The validation value 'strip' requires no validation.
- // The validation value 'preserve' is presently not implemented.
+ // The validation value 'preserve' is currently not implemented.
}
// After any needed element node validation by xsl:element instruction's
diff --git a/src/org/apache/xalan/templates/ElemLiteralResult.java b/src/org/apache/xalan/templates/ElemLiteralResult.java
index eff2964d6..5111b539c 100644
--- a/src/org/apache/xalan/templates/ElemLiteralResult.java
+++ b/src/org/apache/xalan/templates/ElemLiteralResult.java
@@ -1403,7 +1403,10 @@ public class ElemLiteralResult extends ElemUse
// Process xsl:type & xsl:validation attributes, if present
- if ((m_type != null) && (m_validation != null)) {
+ QName type = getType();
+ String validation = getValidation();
+
+ if ((type != null) && (validation != null)) {
throw new TransformerException("XTTE1540 : A literal result element cannot have both the attributes "
+ "'xsl:type' and 'xsl:validation'.", srcLocator);
}
@@ -1411,7 +1414,7 @@ public class ElemLiteralResult extends ElemUse
String nodeName = getNodeName();
String nodeNamespace = getNamespace();
- if (m_type != null) {
+ if (type != null) {
// A literal result element has an attribute "xsl:type".
// An element node constructed needs to be validated
// by this type.
@@ -1436,11 +1439,11 @@ public class ElemLiteralResult extends ElemUse
prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
}
- String typeNsUri = XslTransformEvaluationHelper.getNsUriFromPrefix(m_type.getPrefix(), prefixTable);
+ String typeNsUri = XslTransformEvaluationHelper.getNsUriFromPrefix(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.
- validateXslElementAttributeResultWithBuiltInSchemaType(xmlStr, m_type, xctxt, LITERAL_RESULT_ELEMENT);
+ validateXslElementAttributeResultWithBuiltInSchemaType(xmlStr, type, xctxt, LITERAL_RESULT_ELEMENT);
}
else {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
@@ -1459,17 +1462,17 @@ public class ElemLiteralResult extends ElemUse
}
}
}
- else if (m_validation != null) {
+ else if (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)) {
+ if (!isValidationStrOk(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)) {
+ else if ((Constants.XS_VALIDATION_STRICT_STRING).equals(validation)) {
XSModel xsModel = (XslTransformSharedDatastore.stylesheetRoot).getXsModel();
if (xsModel != null) {
String nodeLocalName = QName.getLocalPart(nodeName);
@@ -1489,7 +1492,7 @@ public class ElemLiteralResult extends ElemUse
+ "a schema.", srcLocator);
}
}
- else if ("lax".equals(m_validation)) {
+ else if ((Constants.XS_VALIDATION_LAX_STRING).equals(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.
@@ -1506,7 +1509,7 @@ public class ElemLiteralResult extends ElemUse
// The validation value 'strip' requires no validation.
- // The validation value 'preserve' is presently not implemented.
+ // The validation value 'preserve' is currently not implemented.
}
// After any needed element node validation by literal result element's
diff --git a/src/org/apache/xalan/templates/ElemTemplateElement.java b/src/org/apache/xalan/templates/ElemTemplateElement.java
index 5828bbf14..03bf1494d 100644
--- a/src/org/apache/xalan/templates/ElemTemplateElement.java
+++ b/src/org/apache/xalan/templates/ElemTemplateElement.java
@@ -25,21 +25,33 @@ import java.util.ArrayList;
import java.util.Enumeration;
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.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.dtm.DTMIterator;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
import org.apache.xml.utils.UnImplNode;
+import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionNode;
import org.apache.xpath.WhitespaceStrippingElementMatcher;
+import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
+import org.apache.xpath.composite.SequenceTypeSupport;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XRTreeFrag;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -74,16 +86,16 @@ public class ElemTemplateElement extends UnImplNode
static final long serialVersionUID = 4440018597841834447L;
/**
- * This field supports implementation of, xsl:for-each-group's grouping key.
+ * This class field supports implementation of, xsl:for-each-group's grouping key.
* An instance of this class, stores this value for a specific xsl:for-each-group
* element within an XSL stylesheet.
*/
private Object m_groupingKey = null;
/**
- * This field supports implementation of, xsl:for-each-group's current-group contents.
- * An instance of this class, stores this value for a specific xsl:for-each-group
- * element within an XSL stylesheet.
+ * This class field supports implementation of, xsl:for-each-group's current-group
+ * contents. An instance of this class, stores this value for a specific
+ * xsl:for-each-group element within an XSL stylesheet.
*/
private List<Integer> m_groupNodesDtmHandles;
@@ -92,11 +104,13 @@ public class ElemTemplateElement extends UnImplNode
*/
private List<XObject> m_tunnelParamObjList = new ArrayList<XObject>();
+ /**
+ * This class field stores an XPath context object.
+ */
private XPathContext m_xpathContext;
/**
* Construct a template element instance.
- *
*/
public ElemTemplateElement(){}
@@ -143,7 +157,64 @@ public class ElemTemplateElement extends UnImplNode
return getNodeName();
}
-
+
+ /**
+ * Class field to denote that, validation originated from
+ * xsl:element instruction.
+ */
+ protected String XSL_ELEMENT = "ELEMENT";
+
+ /**
+ * Class field to denote that, validation originated from
+ * XSL stylesheet literal result element.
+ */
+ protected String LITERAL_RESULT_ELEMENT = "LITERAL_RESULT_ELEMENT";
+
+ /**
+ * Class field to denote that, validation originated from
+ * xsl:attribute instruction.
+ */
+ protected String ATTRIBUTE = "ATTRIBUTE";
+
+ /**
+ * Class field to store value of an attribute named 'type'.
+ */
+ private QName m_type = null;
+
+ /**
+ * Class field to store value of an attribute named 'validation'.
+ */
+ private String m_validation = null;
+
+ /**
+ * Set value of an attribute named 'type'.
+ */
+ public void setType(QName type)
+ {
+ m_type = type;
+ }
+
+ /**
+ * Get value of an attribute named 'type'.
+ */
+ public QName getType() {
+ return m_type;
+ }
+
+ /**
+ * Set value of an attribute named 'validation'.
+ */
+ public void setValidation(String validation)
+ {
+ m_validation = validation;
+ }
+
+ /**
+ * Get value of an attribute named 'validation'.
+ */
+ public String getValidation() {
+ return m_validation;
+ }
/**
* This function will be called on top-level elements
@@ -1807,20 +1878,260 @@ public class ElemTemplateElement extends UnImplNode
}
}
+ /**
+ * Method definition to work with XSLT tunnel parameters.
+ */
public void setTunnelParamObj(XObject var) {
m_tunnelParamObjList.add(var);
}
+ /**
+ * Method definition to work with XSLT tunnel parameters.
+ */
public List<XObject> getTunnelParamObjList() {
return m_tunnelParamObjList;
}
+ /**
+ * Get XPath context object.
+ */
public XPathContext getXPathContext() {
return m_xpathContext;
}
+ /**
+ * Set XPath context object.
+ */
public void setXPathContext(XPathContext xpathContext) {
this.m_xpathContext = xpathContext;
}
+
+ /**
+ * Validate a simple type value produced by xsl:element instruction, literal result element or an
+ * xsl:attribute instruction, by the specified schema built-in simple type.
+ */
+ protected void validateXslElementAttributeResultWithBuiltInSchemaType(String xmlStr, QName typeQname,
+ XPathContext xctxt, String validationSource) 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) {
+ String errMesgStr = null;
+ if (XSL_ELEMENT.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An element node constructed via xsl:element instruction, is not valid according "
+ + "to type xs:" + dataTypeLocalName + " specified as value of "
+ + "xsl:element's attribute 'type'.";
+ }
+ else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
+ errMesgStr = "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'.";
+ }
+ else if (ATTRIBUTE.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An attribute node constructed via xsl:attribute instruction, is not valid according "
+ + "to type xs:" + dataTypeLocalName + " specified as value of "
+ + "xsl:attribute's attribute 'type'.";
+ }
+
+ throw new TransformerException(errMesgStr, srcLocator);
+ }
+ }
+
+ /**
+ * When an XSL instruction xsl:element or a literal result element has an attribute "type" or
+ * "xsl:type" respectively, validate an element node by the specified schema type.
+ */
+ protected void validateXslElementResultWithUserDefinedSchemaType(String nodeName, TransformerImpl transformer,
+ XPathContext xctxt, String xmlStr, XSModel xsModel,
+ String validationSource) 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) {
+ String errMesgStr = null;
+ if (XSL_ELEMENT.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An element node constructed via xsl:element instruction, is not "
+ + "valid according to type " + dataTypeLocalName + " specified "
+ + "as value of xsl:element's attribute 'type'. " + errMesg;
+ }
+ else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
+ errMesgStr = "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;
+ }
+
+ throw new TransformerException(errMesgStr, srcLocator);
+ }
+ }
+ }
+
+ /**
+ * When an XSL instruction xsl:element or a literal result element has an attribute "validation" or
+ * "xsl:validation" respectively, validate an element node by corresponding XML Schema
+ * element declaration.
+ */
+ protected void validateXslElementResultWithSchemaElemDecl(String nodeName, TransformerImpl transformer,
+ XPathContext xctxt,
+ XSElementDeclaration elemDecl, String validationSource) 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) {
+ String errMesgStr = null;
+ if (XSL_ELEMENT.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An error occured while evaluating an XSL stylesheet instruction xsl:element.";
+ }
+ else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An error occured while evaluating an XSL stylesheet literal result element.";
+ }
+
+ throw new TransformerException(errMesgStr, 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) {
+ String errMesgStr = null;
+ if (XSL_ELEMENT.equals(validationSource)) {
+ errMesgStr = "XTTE1540 : An element node constructed via an XSL stylesheet instruction xsl:element, "
+ + "is not valid according to the corresponding element "
+ + "declaration available in the schema. " + errMesg;
+ }
+ else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
+ errMesgStr = "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;
+ }
+
+ throw new TransformerException(errMesgStr, srcLocator);
+ }
+ }
+ }
+
+ /**
+ * Check for the allowed values of "validation" attribute.
+ */
+ protected boolean isValidationStrOk(String validationStr) {
+ return ((Constants.XS_VALIDATION_STRICT_STRING).equals(validationStr) ||
+ (Constants.XS_VALIDATION_LAX_STRING).equals(validationStr) ||
+ (Constants.XS_VALIDATION_PRESERVE_STRING).equals(validationStr) ||
+ (Constants.XS_VALIDATION_STRIP_STRING).equals(validationStr));
+ }
}
diff --git a/src/org/apache/xalan/templates/ElemUse.java b/src/org/apache/xalan/templates/ElemUse.java
index 0619d96f7..825bff12f 100644
--- a/src/org/apache/xalan/templates/ElemUse.java
+++ b/src/org/apache/xalan/templates/ElemUse.java
@@ -20,31 +20,14 @@
*/
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.
@@ -63,64 +46,6 @@ 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;
-
- /**
- * Class field to denote that, validation originated from
- * xsl:element instruction.
- */
- protected String XSL_ELEMENT = "ELEMENT";
-
- /**
- * Class field to denote that, validation originated from
- * XSL stylesheet literal result element.
- */
- protected String LITERAL_RESULT_ELEMENT = "LITERAL_RESULT_ELEMENT";
-
- /**
- * Class field to denote that, validation originated from
- * xsl:attribute instruction.
- */
- protected String ATTRIBUTE = "ATTRIBUTE";
-
- /**
- * 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.
@@ -276,231 +201,6 @@ public class ElemUse extends ElemTemplateElement
m_attributeSetsNames);
}
- }
-
- /**
- * Validate a simple type value produced by xsl:element instruction, literal result element or an
- * xsl:attribute instruction, by the specified schema built-in simple type.
- */
- protected void validateXslElementAttributeResultWithBuiltInSchemaType(String xmlStr, QName typeQname,
- XPathContext xctxt, String validationSource) 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) {
- String errMesgStr = null;
- if (XSL_ELEMENT.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An element node constructed via xsl:element instruction, is not valid according "
- + "to type xs:" + dataTypeLocalName + " specified as value of "
- + "xsl:element's attribute 'type'.";
- }
- else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
- errMesgStr = "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'.";
- }
- else if (ATTRIBUTE.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An attribute node constructed via xsl:attribute instruction, is not valid according "
- + "to type xs:" + dataTypeLocalName + " specified as value of "
- + "xsl:attribute's attribute 'type'.";
- }
-
- throw new TransformerException(errMesgStr, srcLocator);
- }
- }
-
- /**
- * When an XSL instruction xsl:element or a literal result element has an attribute "type" or
- * "xsl:type" respectively, validate an element node by the specified schema type.
- */
- protected void validateXslElementResultWithUserDefinedSchemaType(String nodeName, TransformerImpl transformer,
- XPathContext xctxt, String xmlStr, XSModel xsModel,
- String validationSource) 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) {
- String errMesgStr = null;
- if (XSL_ELEMENT.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An element node constructed via xsl:element instruction, is not "
- + "valid according to type " + dataTypeLocalName + " specified "
- + "as value of xsl:element's attribute 'type'. " + errMesg;
- }
- else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
- errMesgStr = "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;
- }
-
- throw new TransformerException(errMesgStr, srcLocator);
- }
- }
- }
-
- /**
- * When an XSL instruction xsl:element or a literal result element has an attribute "validation" or
- * "xsl:validation" respectively, validate an element node by corresponding XML Schema
- * element declaration.
- */
- protected void validateXslElementResultWithSchemaElemDecl(String nodeName, TransformerImpl transformer,
- XPathContext xctxt,
- XSElementDeclaration elemDecl, String validationSource) 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) {
- String errMesgStr = null;
- if (XSL_ELEMENT.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An error occured while evaluating an XSL stylesheet instruction xsl:element.";
- }
- else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An error occured while evaluating an XSL stylesheet literal result element.";
- }
-
- throw new TransformerException(errMesgStr, 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) {
- String errMesgStr = null;
- if (XSL_ELEMENT.equals(validationSource)) {
- errMesgStr = "XTTE1540 : An element node constructed via an XSL stylesheet instruction xsl:element, "
- + "is not valid according to the corresponding element "
- + "declaration available in the schema. " + errMesg;
- }
- else if (LITERAL_RESULT_ELEMENT.equals(validationSource)) {
- errMesgStr = "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;
- }
-
- throw new TransformerException(errMesgStr, 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/templates/StylesheetRoot.java b/src/org/apache/xalan/templates/StylesheetRoot.java
index 7653e9fb6..5a49ed70d 100644
--- a/src/org/apache/xalan/templates/StylesheetRoot.java
+++ b/src/org/apache/xalan/templates/StylesheetRoot.java
@@ -1728,7 +1728,7 @@ public class StylesheetRoot extends StylesheetComposed
*/
private String getDetailedValidationErrorMesg(String errType, String errMesg,
int lineNo, int colNo, String systemId) {
- String detailedErrMesg = "[" + errType + "] " + systemId + ". Validation error occured at document "
+ String detailedErrMesg = "[" + errType + "] " + systemId + ". Validation error occured at "
+ "location (" + lineNo + "," + colNo +") : " + errMesg;
return detailedErrMesg;
diff --git a/src/org/apache/xpath/objects/XNodeSet.java b/src/org/apache/xpath/objects/XNodeSet.java
index be9ba409b..38b26b232 100644
--- a/src/org/apache/xpath/objects/XNodeSet.java
+++ b/src/org/apache/xpath/objects/XNodeSet.java
@@ -26,6 +26,7 @@ import java.util.List;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.DTMManager;
+import org.apache.xml.utils.QName;
import org.apache.xml.utils.XMLString;
import org.apache.xpath.NodeSetDTM;
import org.apache.xpath.XPathContext;
@@ -54,6 +55,18 @@ public class XNodeSet extends NodeSequence
* Default constructor for derived objects.
*/
protected XNodeSet() { }
+
+ /**
+ * Class field to store value of an attribute named 'type', for
+ * validating this xdm node object.
+ */
+ private QName m_type = null;
+
+ /**
+ * Class field to store value of an attribute named 'validation', for
+ * validating this xdm node object.
+ */
+ private String m_validation = null;
/**
* Construct a XNodeSet object.
@@ -953,7 +966,7 @@ public class XNodeSet extends NodeSequence
return compare(obj2, S_NEQ);
}
- /*
+ /**
* Check whether fully qualified names of two XML nodes are equal.
*/
private boolean isNodeNameEqual(Node node1, Node node2) {
@@ -983,7 +996,7 @@ public class XNodeSet extends NodeSequence
return isNodeNameEqual;
}
- /*
+ /**
* Check whether two XML namespace names are equal.
*/
private boolean isNsNameEqual(String nsName1, String nsName2) {
@@ -999,6 +1012,23 @@ public class XNodeSet extends NodeSequence
return isNsNameEqual;
}
+
+ public void setTypeAttrForValidation(QName type) {
+ m_type = type;
+ }
+
+ public QName getTypeAttrForValidation() {
+ return m_type;
+ }
+
+ public void setValidationAttrForValidation(String validation) {
+ m_validation = validation;
+ }
+
+ public String getValidationAttrForValidation() {
+ return m_validation;
+ }
+
}
/**
diff --git a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
index cf28a5ac1..afba5906a 100644
--- a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
@@ -86,7 +86,8 @@ import org.junit.runners.Suite.SuiteClasses;
XPathGeneralComparisonOpTests.class, FnMapFindTests.class, XPathNumericArithmeticTests.class,
XslTunnelParameterTests.class, FuncBooleanValuesTests.class, XslElementValidationTests.class,
XslLiteralResultElementValidationTests.class, XslAttributeValidationTests.class,
- XPathExprFunctionCallSuffixTests.class, XslEvaluateTests.class, XslValueofTests.class })
+ XPathExprFunctionCallSuffixTests.class, XslEvaluateTests.class, XslValueofTests.class,
+ XslCopyofValidationTests.class })
public class Xsl3TestSuite1 {
}
diff --git a/tests/org/apache/xalan/xslt3/XslCopyofValidationTests.java b/tests/org/apache/xalan/xslt3/XslCopyofValidationTests.java
new file mode 100644
index 000000000..2bd878109
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/XslCopyofValidationTests.java
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XSLConstants;
+import org.apache.xalan.util.XSLTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSL stylesheet test case to test, xsl:copy-of instruction's
+ * attributes 'type' and 'validation'.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class XslCopyofValidationTests extends XSLTransformTestsUtil {
+
+ private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "xsl_copyof_validation/";
+
+ private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "xsl_copyof_validation/gold/";
+
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ // no op
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ xmlDocumentBuilderFactory = null;
+ xmlDocumentBuilder = null;
+ xslTransformerFactory = null;
+ }
+
+ @Test
+ public void xslCopyofValidationTest1() {
+ 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);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslCopyofValidationTest2() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";
+
+ setXmlValidationProperty(true);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslCopyofValidationTest3() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";
+
+ setXmlValidationProperty(true);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslCopyofValidationTest4() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";
+
+ setXmlValidationProperty(true);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslCopyofValidationTest5() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";
+
+ setXmlValidationProperty(true);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslCopyofValidationTest6() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";
+
+ setXmlValidationProperty(true);
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+}
diff --git a/tests/xsl_copyof_validation/gold/test1.out b/tests/xsl_copyof_validation/gold/test1.out
new file mode 100644
index 000000000..545df45d8
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test1.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA id="6">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA id="7">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA id="8">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA id="9">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA id="10">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/gold/test2.out b/tests/xsl_copyof_validation/gold/test2.out
new file mode 100644
index 000000000..545df45d8
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test2.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA id="6">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA id="7">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA id="8">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA id="9">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA id="10">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/gold/test3.out b/tests/xsl_copyof_validation/gold/test3.out
new file mode 100644
index 000000000..545df45d8
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test3.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA id="6">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA id="7">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA id="8">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA id="9">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA id="10">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/gold/test4.out b/tests/xsl_copyof_validation/gold/test4.out
new file mode 100644
index 000000000..545df45d8
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test4.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA id="6">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA id="7">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA id="8">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA id="9">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA id="10">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/gold/test5.out b/tests/xsl_copyof_validation/gold/test5.out
new file mode 100644
index 000000000..e402d8fa5
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test5.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA val="1">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA val="2">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA val="3">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA val="4">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA val="5">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/gold/test6.out b/tests/xsl_copyof_validation/gold/test6.out
new file mode 100644
index 000000000..e402d8fa5
--- /dev/null
+++ b/tests/xsl_copyof_validation/gold/test6.out
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <newA val="1">
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ <a val="1">a1</a>
+ </newA>
+ <newA val="2">
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ <a val="2">a2</a>
+ </newA>
+ <newA val="3">
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ <a val="3">a3</a>
+ </newA>
+ <newA val="4">
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ <a val="4">a4</a>
+ </newA>
+ <newA val="5">
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ <a val="5">a5</a>
+ </newA>
+</result>
diff --git a/tests/xsl_copyof_validation/info_1.xsd b/tests/xsl_copyof_validation/info_1.xsd
new file mode 100644
index 000000000..237528324
--- /dev/null
+++ b/tests/xsl_copyof_validation/info_1.xsd
@@ -0,0 +1,52 @@
+<?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" type="aType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="aType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="val"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:attribute name="val">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ <xs:maxInclusive value="10"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:element name="newA">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="a" type="aType" minOccurs="3" maxOccurs="3"/>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:integer"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="newAType">
+ <xs:sequence>
+ <xs:element name="a" type="aType" minOccurs="3" maxOccurs="3"/>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:integer"/>
+ </xs:complexType>
+
+ <xs:attribute name="id" type="idType"/>
+
+ <xs:simpleType name="idType">
+ <xs:restriction base="xs:integer">
+ <xs:maxInclusive value="10"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+</xs:schema>
diff --git a/tests/xsl_copyof_validation/test1.xml b/tests/xsl_copyof_validation/test1.xml
new file mode 100644
index 000000000..0842980ae
--- /dev/null
+++ b/tests/xsl_copyof_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>
diff --git a/tests/xsl_copyof_validation/test1.xsl b/tests/xsl_copyof_validation/test1.xsl
new file mode 100644
index 000000000..668eb93a4
--- /dev/null
+++ b/tests/xsl_copyof_validation/test1.xsl
@@ -0,0 +1,52 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'type' when validating
+ an element node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA id="{position() + 5}">
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1/newA" type="newAType"/>
+ </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_copyof_validation/test2.xsl b/tests/xsl_copyof_validation/test2.xsl
new file mode 100644
index 000000000..922b2ca6d
--- /dev/null
+++ b/tests/xsl_copyof_validation/test2.xsl
@@ -0,0 +1,52 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'validation' when validating
+ an element node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA id="{position() + 5}">
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1/newA" validation="strict"/>
+ </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_copyof_validation/test3.xsl b/tests/xsl_copyof_validation/test3.xsl
new file mode 100644
index 000000000..4cfbf513a
--- /dev/null
+++ b/tests/xsl_copyof_validation/test3.xsl
@@ -0,0 +1,52 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'type' when validating
+ an element node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA id="{position() + 5}">
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1" type="newAType"/>
+ </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_copyof_validation/test4.xsl b/tests/xsl_copyof_validation/test4.xsl
new file mode 100644
index 000000000..0d0f16f75
--- /dev/null
+++ b/tests/xsl_copyof_validation/test4.xsl
@@ -0,0 +1,52 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'validation' when validating
+ an element node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA id="{position() + 5}">
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1" validation="strict"/>
+ </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_copyof_validation/test5.xsl b/tests/xsl_copyof_validation/test5.xsl
new file mode 100644
index 000000000..132754ecb
--- /dev/null
+++ b/tests/xsl_copyof_validation/test5.xsl
@@ -0,0 +1,53 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'type' when validating
+ an attribute node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA>
+ <xsl:copy-of select="@val" type="idType"/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1"/>
+ </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_copyof_validation/test6.xsl b/tests/xsl_copyof_validation/test6.xsl
new file mode 100644
index 000000000..7c860093d
--- /dev/null
+++ b/tests/xsl_copyof_validation/test6.xsl
@@ -0,0 +1,53 @@
+<?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 XSL stylesheet test case to test, xsl:copy-of
+ instruction's attribute 'type' when validating
+ an attribute node. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:import-schema schema-location="info_1.xsd"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:apply-templates select="a"/>
+ </result>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:variable name="var1">
+ <newA>
+ <xsl:copy-of select="@val" validation="strict"/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ <xsl:copy-of select="."/>
+ </newA>
+ </xsl:variable>
+ <xsl:copy-of select="$var1"/>
+ </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