1 package net.sf.saxon.style; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.expr.*; 4 import net.sf.saxon.instruct.*; 5 import net.sf.saxon.om.AttributeCollection; 6 import net.sf.saxon.om.Axis; 7 import net.sf.saxon.om.Validation; 8 import net.sf.saxon.pattern.NodeKindTest; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.type.SchemaType; 11 import net.sf.saxon.value.EmptySequence; 12 import net.sf.saxon.value.SequenceType; 13 14 17 18 public class XSLCopy extends StyleElement { 19 20 private String use; private AttributeSet[] attributeSets = null; 22 private boolean copyNamespaces = true; 23 private boolean inheritNamespaces = true; 24 private int validationAction = Validation.PRESERVE; 25 private SchemaType schemaType = null; 26 27 31 32 public boolean isInstruction() { 33 return true; 34 } 35 36 40 41 public boolean mayContainSequenceConstructor() { 42 return true; 43 } 44 45 public void prepareAttributes() throws XPathException { 46 47 AttributeCollection atts = getAttributeList(); 48 String copyNamespacesAtt = null; 49 String validationAtt = null; 50 String typeAtt = null; 51 String inheritAtt = null; 52 53 for (int a=0; a<atts.getLength(); a++) { 54 int nc = atts.getNameCode(a); 55 String f = getNamePool().getClarkName(nc); 56 if (f==StandardNames.USE_ATTRIBUTE_SETS) { 57 use = atts.getValue(a); 58 } else if (f==StandardNames.COPY_NAMESPACES) { 59 copyNamespacesAtt = atts.getValue(a).trim(); 60 } else if (f==StandardNames.TYPE) { 61 typeAtt = atts.getValue(a).trim(); 62 } else if (f==StandardNames.VALIDATION) { 63 validationAtt = atts.getValue(a).trim(); 64 } else if (f==StandardNames.INHERIT_NAMESPACES) { 65 inheritAtt = atts.getValue(a).trim(); 66 } else { 67 checkUnknownAttribute(nc); 68 } 69 } 70 71 if (copyNamespacesAtt == null) { 72 copyNamespaces = true; 73 } else { 74 if (copyNamespacesAtt.equals("yes")) { 75 copyNamespaces = true; 76 } else if (copyNamespacesAtt.equals("no")) { 77 copyNamespaces = false; 78 } else { 79 compileError("Value of copy-namespaces must be 'yes' or 'no'", "XTSE0020"); 80 } 81 } 82 83 if (typeAtt != null && validationAtt != null) { 84 compileError("The type and validation attributes must not both be specified", "XTSE1505"); 85 } 86 87 if (validationAtt != null) { 88 validationAction = Validation.getCode(validationAtt); 89 if (validationAction != Validation.STRIP && !getConfiguration().isSchemaAware(Configuration.XSLT)) { 90 compileError("To perform validation, a schema-aware XSLT processor is needed", "XTSE1660"); 91 } 92 } else { 93 validationAction = getContainingStylesheet().getDefaultValidation(); 94 } 95 96 if (typeAtt != null) { 97 schemaType = getSchemaType(typeAtt); 98 if (!getConfiguration().isSchemaAware(Configuration.XSLT)) { 99 compileError("The @type attribute is available only with a schema-aware XSLT processor", "XTSE1660"); 100 } 101 } 102 if (inheritAtt != null) { 103 if (inheritAtt.equals("yes")) { 104 inheritNamespaces = true; 105 } else if (inheritAtt.equals("no")) { 106 inheritNamespaces = false; 107 } else { 108 compileError("The @inherit-namespaces attribute has permitted values (yes, no)", "XTSE0020"); 109 } 110 } 111 112 if (validationAction == Validation.PRESERVE && !copyNamespaces) { 113 compileError("copy-namespaces must be set to 'yes' when validation is set to 'preserve'", "XTSE0950"); 114 } 115 } 116 117 public void validate() throws XPathException { 118 checkWithinTemplate(); 119 if (use!=null) { 120 attributeSets = getAttributeSets(use, null); } 122 } 123 124 public Expression compile(Executable exec) throws XPathException { 125 Copy inst = new Copy(copyNamespaces, 126 inheritNamespaces, 127 schemaType, 128 validationAction); 129 Expression content = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true); 130 131 if (attributeSets != null) { 132 UseAttributeSets use = new UseAttributeSets(attributeSets); 133 Expression condition = new InstanceOfExpression( 136 new ContextItemExpression(), 137 SequenceType.makeSequenceType(NodeKindTest.ELEMENT, StaticProperty.EXACTLY_ONE)); 138 Expression choice = new IfExpression(condition, use, EmptySequence.getInstance()); 139 if (content == null) { 140 content = choice; 141 } else { 142 content = Block.makeBlock(choice, content); 143 } 144 } 145 146 if (content == null) { 147 content = EmptySequence.getInstance(); 148 } 149 inst.setContentExpression(content); 150 ExpressionTool.makeParentReferences(inst); 151 return inst; 152 } 153 154 } 155 156 | Popular Tags |