1 package net.sf.saxon.style; 2 import net.sf.saxon.Err; 3 import net.sf.saxon.expr.*; 4 import net.sf.saxon.instruct.ApplyTemplates; 5 import net.sf.saxon.instruct.Executable; 6 import net.sf.saxon.om.*; 7 import net.sf.saxon.sort.SortExpression; 8 import net.sf.saxon.sort.SortKeyDefinition; 9 import net.sf.saxon.trans.Mode; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.type.Type; 12 import net.sf.saxon.value.SequenceType; 13 import net.sf.saxon.value.Whitespace; 14 15 16 19 20 public class XSLApplyTemplates extends StyleElement { 21 22 private Expression select; 23 private int modeNameCode = -1; private boolean useCurrentMode = false; 25 private boolean useTailRecursion = false; 26 private Mode mode; 27 private String modeAttribute; 28 29 33 34 public boolean isInstruction() { 35 return true; 36 } 37 38 39 public void prepareAttributes() throws XPathException { 40 41 AttributeCollection atts = getAttributeList(); 42 43 String selectAtt = null; 44 45 for (int a=0; a<atts.getLength(); a++) { 46 int nc = atts.getNameCode(a); 47 String f = getNamePool().getClarkName(nc); 48 if (f==StandardNames.MODE) { 49 modeAttribute = atts.getValue(a).trim(); 50 } else if (f==StandardNames.SELECT) { 51 selectAtt = atts.getValue(a); 52 } else { 53 checkUnknownAttribute(nc); 54 } 55 } 56 57 if (modeAttribute!=null) { 58 if (modeAttribute.equals("#current")) { 59 useCurrentMode = true; 60 } else if (modeAttribute.equals("#default")) { 61 } else { 63 try { 64 modeNameCode = makeNameCode(modeAttribute.trim()); 65 } catch (NamespaceException err) { 66 reportInvalidAttribute(err.getMessage(), "XTSE0280"); 67 modeNameCode = -1; 68 } catch (XPathException err) { 69 reportInvalidAttribute("Mode name " + Err.wrap(modeAttribute) + " is not a valid QName", "XTSE0280"); 70 modeNameCode = -1; 71 } 72 } 73 } 74 75 if (selectAtt!=null) { 76 select = makeExpression(selectAtt); 77 } 78 } 79 80 public void validate() throws XPathException { 81 82 checkWithinTemplate(); 83 84 if (!useCurrentMode) { 86 mode = getPrincipalStylesheet().getRuleManager().getMode(modeNameCode); 87 } 88 89 91 AxisIterator kids = iterateAxis(Axis.CHILD); 92 while (true) { 93 NodeInfo child = (NodeInfo)kids.next(); 94 if (child == null) { 95 break; 96 } 97 if (child instanceof XSLSort) { 98 } else if (child instanceof XSLWithParam) { 100 } else if (child.getNodeKind() == Type.TEXT) { 102 if (!Whitespace.isWhite(child.getStringValueCS())) { 104 compileError("No character data is allowed within xsl:apply-templates", "XTSE0010"); 105 } 106 } else { 107 compileError("Invalid element within xsl:apply-templates", "XTSE0010"); 108 } 109 } 110 111 if (select==null) { 112 select = new AxisExpression(Axis.CHILD, null); 113 } 114 115 select = typeCheck("select", select); 116 try { 117 RoleLocator role = 118 new RoleLocator(RoleLocator.INSTRUCTION, "xsl:apply-templates/select", 0, null); 119 role.setSourceLocator(new ExpressionLocation(this)); 120 role.setErrorCode("XTTE0520"); 121 select = TypeChecker.staticTypeCheck(select, 122 SequenceType.NODE_SEQUENCE, 123 false, role, getStaticContext()); 124 } catch (XPathException err) { 125 compileError(err); 126 } 127 128 } 129 130 134 135 public void markTailCalls() { 136 useTailRecursion = true; 137 } 138 139 140 public Expression compile(Executable exec) throws XPathException { 141 SortKeyDefinition[] sortKeys = makeSortKeys(); 142 if (sortKeys != null) { 143 useTailRecursion = false; 144 } 145 Expression sortedSequence = select; 146 if (sortKeys != null) { 147 sortedSequence = new SortExpression(select, sortKeys); 148 ExpressionTool.makeParentReferences(sortedSequence); 149 } 150 ApplyTemplates app = new ApplyTemplates( 151 sortedSequence, 152 useCurrentMode, 153 useTailRecursion, 154 mode, 155 backwardsCompatibleModeIsEnabled()); 156 app.setActualParameters(getWithParamInstructions(exec, false, app), 157 getWithParamInstructions(exec, true, app)); 158 ExpressionTool.makeParentReferences(app); 159 return app; 160 } 161 162 } 163 164 | Popular Tags |