package client.net.sf.saxon.ce.style;
import client.net.sf.saxon.ce.event.Stripper;
import client.net.sf.saxon.ce.expr.Expression;
import client.net.sf.saxon.ce.expr.instruct.Executable;
import client.net.sf.saxon.ce.expr.instruct.Template;
import client.net.sf.saxon.ce.om.*;
import client.net.sf.saxon.ce.pattern.*;
import client.net.sf.saxon.ce.trans.StripSpaceRules;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.Type;
import client.net.sf.saxon.ce.tree.util.StringTokenizer;
/**
* An xsl:preserve-space or xsl:strip-space elements in stylesheet. <br>
*/
public class XSLPreserveSpace extends StyleElement {
private String elements;
/**
* Ask whether this node is a declaration, that is, a permitted child of xsl:stylesheet
* (including xsl:include and xsl:import).
* @return true for this element
*/
@Override
public boolean isDeclaration() {
return true;
}
public void prepareAttributes() throws XPathException {
AttributeCollection atts = getAttributeList();
for (int a=0; a<atts.getLength(); a++) {
int nc = atts.getNameCode(a);
String f = getNamePool().getClarkName(nc);
if (f.equals(StandardNames.ELEMENTS)) {
elements = atts.getValue(a);
} else {
checkUnknownAttribute(nc);
}
}
if (elements==null) {
reportAbsence("elements");
elements="*"; // for error recovery
}
}
public void validate(Declaration decl) throws XPathException {
checkEmpty();
checkTopLevel(null);
}
public Expression compile(Executable exec, Declaration decl) throws XPathException
{
Template preserve =
(getFingerprint() == StandardNames.XSL_PRESERVE_SPACE ? Stripper.PRESERVE : Stripper.STRIP);
StripSpaceRules stripperRules = getPrincipalStylesheetModule().getStripperRules();
// elements is a space-separated list of element names
StringTokenizer st = new StringTokenizer(elements, " \t\n\r", false);
while (st.hasMoreTokens()) {
String s = st.nextToken();
NodeTest nt;
if (s.equals("*")) {
nt = NodeKindTest.ELEMENT;
stripperRules.addRule(nt, preserve, decl.getModule(), decl.getSourceElement().getLineNumber());
} else if (s.endsWith(":*")) {
if (s.length()==2) {
compileError("No prefix before ':*'");
}
String prefix = s.substring(0, s.length()-2);
String uri = getURIForPrefix(prefix, false);
nt = new NamespaceTest(getNamePool(), Type.ELEMENT, uri);
stripperRules.addRule(nt, preserve, decl.getModule(), decl.getSourceElement().getLineNumber());
} else if (s.startsWith("*:")) {
if (s.length()==2) {
compileError("No local name after '*:'");
}
String localname = s.substring(2);
nt = new LocalNameTest(getNamePool(), Type.ELEMENT, localname);
stripperRules.addRule(nt, preserve, decl.getModule(), decl.getSourceElement().getLineNumber());
} else {
String prefix;
String localName;
String uri;
try {
String[] parts = NameChecker.getQNameParts(s);
prefix = parts[0];
if (parts[0].equals("")) {
uri = getDefaultXPathNamespace();
} else {
uri = getURIForPrefix(prefix, false);
if (uri == null) {
undeclaredNamespaceError(prefix, "XTSE0280");
return null;
}
}
localName = parts[1];
} catch (QNameException err) {
compileError("Element name " + s + " is not a valid QName", "XTSE0280");
return null;
}
NamePool target = getNamePool();
int nameCode = target.allocate("", uri, localName);
nt = new NameTest(Type.ELEMENT, nameCode, getNamePool());
stripperRules.addRule(nt, preserve, decl.getModule(), decl.getSourceElement().getLineNumber());
}
}
return null;
}
}
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.