1 package net.sf.saxon.style; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.expr.Expression; 4 import net.sf.saxon.expr.ExpressionTool; 5 import net.sf.saxon.instruct.Executable; 6 import net.sf.saxon.instruct.ResultDocument; 7 import net.sf.saxon.om.*; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.ItemType; 10 import net.sf.saxon.type.SchemaType; 11 import net.sf.saxon.value.EmptySequence; 12 import net.sf.saxon.value.StringValue; 13 14 import java.util.*; 15 16 25 26 public class XSLResultDocument extends StyleElement { 27 28 private static final HashSet fans = new HashSet(25); 30 static { 31 fans.add(StandardNames.METHOD); 32 fans.add(StandardNames.OUTPUT_VERSION); 33 fans.add(StandardNames.BYTE_ORDER_MARK); 34 fans.add(StandardNames.INDENT); 35 fans.add(StandardNames.ENCODING); 36 fans.add(StandardNames.MEDIA_TYPE); 37 fans.add(StandardNames.DOCTYPE_SYSTEM); 38 fans.add(StandardNames.DOCTYPE_PUBLIC); 39 fans.add(StandardNames.OMIT_XML_DECLARATION); 40 fans.add(StandardNames.STANDALONE); 41 fans.add(StandardNames.CDATA_SECTION_ELEMENTS); 42 fans.add(StandardNames.INCLUDE_CONTENT_TYPE); 43 fans.add(StandardNames.ESCAPE_URI_ATTRIBUTES); 44 fans.add(StandardNames.UNDECLARE_PREFIXES); 45 fans.add(StandardNames.NORMALIZATION_FORM); 46 fans.add(StandardNames.SAXON_NEXT_IN_CHAIN); 47 fans.add(StandardNames.SAXON_CHARACTER_REPRESENTATION); 48 fans.add(StandardNames.SAXON_INDENT_SPACES); 49 fans.add(StandardNames.SAXON_REQUIRE_WELL_FORMED); 50 } 51 52 private Expression href; 53 private int format = -1; private int validationAction = Validation.STRIP; 55 private SchemaType schemaType = null; 56 private HashMap serializationAttributes = new HashMap(20); 57 58 62 63 public boolean isInstruction() { 64 return true; 65 } 66 67 71 72 public boolean mayContainSequenceConstructor() { 73 return true; 74 } 75 76 84 85 protected ItemType getReturnedItemType() { 86 return null; 87 } 88 89 public void prepareAttributes() throws XPathException { 90 AttributeCollection atts = getAttributeList(); 91 92 String formatAttribute = null; 93 String hrefAttribute = null; 94 String validationAtt = null; 95 String typeAtt = null; 96 String useCharacterMapsAtt = null; 97 98 99 for (int a=0; a<atts.getLength(); a++) { 100 int nc = atts.getNameCode(a); 101 String f = getNamePool().getClarkName(nc); 102 if (f==StandardNames.FORMAT) { 103 formatAttribute = atts.getValue(a).trim(); 104 } else if (f==StandardNames.HREF) { 105 hrefAttribute = atts.getValue(a).trim(); 106 } else if (f==StandardNames.VALIDATION) { 107 validationAtt = atts.getValue(a).trim(); 108 } else if (f==StandardNames.TYPE) { 109 typeAtt = atts.getValue(a).trim(); 110 } else if (f==StandardNames.USE_CHARACTER_MAPS) { 111 useCharacterMapsAtt = atts.getValue(a).trim(); 112 } else if (fans.contains(f) || !(f.startsWith("{}"))) { 113 String val = atts.getValue(a).trim(); 115 Expression exp = makeAttributeValueTemplate(val); 116 serializationAttributes.put(new Integer (nc&0xfffff), exp); 117 } else { 118 checkUnknownAttribute(nc); 119 } 120 } 121 122 if (hrefAttribute==null) { 123 } else { 125 href = makeAttributeValueTemplate(hrefAttribute); 126 } 127 128 if (formatAttribute!=null) { 129 try { 130 format = makeNameCode(formatAttribute.trim()) & 0xfffff; 131 } catch (NamespaceException err) { 132 compileError(err.getMessage(), "XTSE0280"); 133 } catch (XPathException err) { 134 compileError(err.getMessage()); 135 } 136 } 137 138 if (validationAtt==null) { 139 validationAction = getContainingStylesheet().getDefaultValidation(); 140 } else { 141 validationAction = Validation.getCode(validationAtt); 142 if (validationAction != Validation.STRIP && !getConfiguration().isSchemaAware(Configuration.XSLT)) { 143 compileError("To perform validation, a schema-aware XSLT processor is needed", "XTSE1660"); 144 } 145 if (validationAction == Validation.INVALID) { 146 compileError("Invalid value of @validation attribute", "XTSE0020"); 147 } 148 } 149 if (typeAtt!=null) { 150 if (!getConfiguration().isSchemaAware(Configuration.XSLT)) { 151 compileError("The @type attribute is available only with a schema-aware XSLT processor", "XTSE1660"); 152 } 153 schemaType = getSchemaType(typeAtt); 154 } 155 156 if (typeAtt != null && validationAtt != null) { 157 compileError("The @validation and @type attributes are mutually exclusive", "XTSE1505"); 158 } 159 160 if (useCharacterMapsAtt != null) { 161 String s = XSLOutput.prepareCharacterMaps(this, useCharacterMapsAtt, new Properties()); 162 serializationAttributes.put( 163 new Integer (getNamePool().allocate("", "", StandardNames.USE_CHARACTER_MAPS)), 164 new StringValue(s)); 165 } 166 } 167 168 public void validate() throws XPathException { 169 checkWithinTemplate(); 170 if (!getPreparedStylesheet().getConfiguration().isAllowExternalFunctions()) { 171 compileError("xsl:result-document is disabled when extension functions are disabled"); 172 } 173 href = typeCheck("href", href); 174 Iterator it = serializationAttributes.keySet().iterator(); 175 boolean methodSpecified = false; 176 while (it.hasNext()) { 177 Integer fp = (Integer )it.next(); 178 String displayName = getNamePool().getDisplayName(fp.intValue()); 179 if (displayName.equals(StandardNames.METHOD)) { 180 methodSpecified = true; 181 } 182 final Expression exp1 = (Expression)serializationAttributes.get(fp); 183 final Expression exp2 = typeCheck(displayName, exp1); 184 if (exp1 != exp2) { 185 serializationAttributes.put(fp, exp2); 186 } 187 } 188 189 190 } 191 192 public Expression compile(Executable exec) throws XPathException { 193 Properties props; 194 try { 195 props = getPrincipalStylesheet().gatherOutputProperties(format); 196 } catch (XPathException err) { 197 compileError("Named output format has not been defined", "XTSE1460"); 198 return null; 199 } 200 201 204 Integer key = new Integer (getNamePool().allocate("", "", StandardNames.METHOD)); 205 if (props.getProperty("method") == null && serializationAttributes.get(key) == null) { 206 AxisIterator kids = iterateAxis(Axis.CHILD); 207 NodeInfo first = (NodeInfo)kids.next(); 208 if (first instanceof LiteralResultElement) { 209 if (first.getFingerprint() == getNamePool().allocate("", NamespaceConstant.XHTML, "html")) { 210 if (backwardsCompatibleModeIsEnabled()) { 211 props.setProperty("method", "xml"); 212 } else { 213 props.setProperty("method", "xhtml"); 214 } 215 } else if (first.getLocalPart().equalsIgnoreCase("html") && first.getURI().equals("")) { 216 props.setProperty("method", "html"); 217 } else { 218 props.setProperty("method", "xml"); 219 } 220 } 221 } 222 223 ArrayList fixed = new ArrayList(10); 224 boolean needsNamespaceContext = false; 225 for (Iterator it=serializationAttributes.keySet().iterator(); it.hasNext();) { 226 Integer fp = (Integer )it.next(); 227 Expression exp = (Expression)serializationAttributes.get(fp); 228 if (exp instanceof StringValue) { 229 String s = ((StringValue)exp).getStringValue(); 230 try { 231 ResultDocument.setSerializationProperty(props, fp.intValue(), s, 232 getNamePool(), getStaticContext().getNamespaceResolver()); 233 fixed.add(fp); 234 } catch (XPathException e) { 235 if (NamespaceConstant.SAXON.equals(e.getErrorCodeNamespace())) { 236 compileWarning(e.getMessage(), e.getErrorCodeLocalPart()); 237 } else { 238 compileError(e); 239 } 240 } 241 } else { 242 String lname = getNamePool().getLocalName(fp.intValue()); 243 if (lname.equals("method") || lname.equals("cdata-section-elements")) { 244 needsNamespaceContext = true; 245 } 246 } 247 } 248 for (Iterator it=fixed.iterator(); it.hasNext();) { 249 serializationAttributes.remove(it.next()); 250 } 251 252 ResultDocument inst = new ResultDocument(props, 253 href, 254 getBaseURI(), 255 validationAction, 256 schemaType, 257 serializationAttributes, 258 (needsNamespaceContext ? getStaticContext().getNamespaceResolver() : null)); 259 260 Expression b = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true); 261 if (b == null) { 262 b = EmptySequence.getInstance(); 263 } 264 inst.setContent(b); 265 ExpressionTool.makeParentReferences(inst); 266 return inst; 267 } 268 269 } 270 271 | Popular Tags |