net.sf.saxon.style.XSLNumber Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of saxon9 Show documentation
Show all versions of saxon9 Show documentation
Provides a basic XSLT 2.0 and XQuery 1.0 processor (W3C Recommendations,
January 2007). Command line interfaces and implementations of several
Java APIs (DOM, XPath, s9api) are also included.
The newest version!
package net.sf.saxon.style;
import net.sf.saxon.expr.*;
import net.sf.saxon.instruct.Executable;
import net.sf.saxon.instruct.NumberInstruction;
import net.sf.saxon.instruct.ValueOf;
import net.sf.saxon.number.NumberFormatter;
import net.sf.saxon.number.Numberer;
import net.sf.saxon.number.Numberer_en;
import net.sf.saxon.om.AttributeCollection;
import net.sf.saxon.om.StandardNames;
import net.sf.saxon.pattern.NodeKindTest;
import net.sf.saxon.pattern.Pattern;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.ItemType;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.Whitespace;
/**
* An xsl:number element in the stylesheet.
*/
public class XSLNumber extends StyleElement {
private static final int SINGLE = 0;
private static final int MULTI = 1;
private static final int ANY = 2;
private static final int SIMPLE = 3;
private int level;
private Pattern count = null;
private Pattern from = null;
private Expression select = null;
private Expression value = null;
private Expression format = null;
private Expression groupSize = null;
private Expression groupSeparator = null;
private Expression letterValue = null;
private Expression lang = null;
private Expression ordinal = null;
private NumberFormatter formatter = null;
private Numberer numberer = null;
private boolean hasVariablesInPatterns = false;
private static Numberer defaultNumberer = new Numberer_en();
/**
* Determine whether this node is an instruction.
* @return true - it is an instruction
*/
public boolean isInstruction() {
return true;
}
/**
* Determine the type of item returned by this instruction (only relevant if
* it is an instruction).
* @return the item type returned
*/
protected ItemType getReturnedItemType() {
return NodeKindTest.TEXT;
}
public void prepareAttributes() throws XPathException {
AttributeCollection atts = getAttributeList();
String selectAtt = null;
String valueAtt = null;
String countAtt = null;
String fromAtt = null;
String levelAtt = null;
String formatAtt = null;
String gsizeAtt = null;
String gsepAtt = null;
String langAtt = null;
String letterValueAtt = null;
String ordinalAtt = null;
for (int a=0; a=0) {
hasVariablesInPatterns = true;
}
}
if (fromAtt!=null) {
from = makePattern(fromAtt);
if (fromAtt.indexOf('$')>=0) {
hasVariablesInPatterns = true;
}
}
if (levelAtt==null) {
level = SINGLE;
} else if (levelAtt.equals("single")) {
level = SINGLE;
} else if (levelAtt.equals("multiple")) {
level = MULTI;
} else if (levelAtt.equals("any")) {
level = ANY;
} else {
compileError("Invalid value for level attribute", "XTSE0020");
}
if (level==SINGLE && from==null && count==null) {
level=SIMPLE;
}
if (formatAtt != null) {
format = makeAttributeValueTemplate(formatAtt);
if (format instanceof StringLiteral) {
formatter = new NumberFormatter();
formatter.prepare(((StringLiteral)format).getStringValue());
}
// else we'll need to allocate the formatter at run-time
} else {
formatter = new NumberFormatter();
formatter.prepare("1");
}
if (gsepAtt!=null && gsizeAtt!=null) {
// the spec says that if only one is specified, it is ignored
groupSize = makeAttributeValueTemplate(gsizeAtt);
groupSeparator = makeAttributeValueTemplate(gsepAtt);
}
if (langAtt==null) {
numberer = defaultNumberer;
} else {
lang = makeAttributeValueTemplate(langAtt);
if (lang instanceof StringLiteral) {
numberer = makeNumberer(((StringLiteral)lang).getStringValue());
} // else we allocate a numberer at run-time
}
if (letterValueAtt != null) {
letterValue = makeAttributeValueTemplate(letterValueAtt);
}
if (ordinalAtt != null) {
ordinal = makeAttributeValueTemplate(ordinalAtt);
}
}
public void validate() throws XPathException {
checkEmpty();
select = typeCheck("select", select);
value = typeCheck("value", value);
format = typeCheck("format", format);
groupSize = typeCheck("group-size", groupSize);
groupSeparator = typeCheck("group-separator", groupSeparator);
letterValue = typeCheck("letter-value", letterValue);
ordinal = typeCheck("ordinal", ordinal);
lang = typeCheck("lang", lang);
from = typeCheck("from", from);
count = typeCheck("count", count);
if (select != null) {
try {
RoleLocator role =
new RoleLocator(RoleLocator.INSTRUCTION, "xsl:number/select", 0, null);
role.setSourceLocator(new ExpressionLocation(this));
role.setErrorCode("XTTE1000");
select = TypeChecker.staticTypeCheck(select,
SequenceType.SINGLE_NODE,
false, role, makeExpressionVisitor());
} catch (XPathException err) {
compileError(err);
}
}
}
public Expression compile(Executable exec) throws XPathException {
NumberInstruction expr = new NumberInstruction (exec.getConfiguration(),
select,
level,
count,
from,
value,
format,
groupSize,
groupSeparator,
letterValue,
ordinal,
lang,
formatter,
numberer,
hasVariablesInPatterns,
backwardsCompatibleModeIsEnabled());
int loc = getStaticContext().getLocationMap().allocateLocationId(getSystemId(), getLineNumber());
expr.setLocationId(loc);
ValueOf inst = new ValueOf(expr, false, false);
inst.setLocationId(allocateLocationId(getSystemId(), getLineNumber()));
inst.setIsNumberingInstruction();
return inst;
}
/**
* Load a Numberer class for a given language and check it is OK.
*/
protected Numberer makeNumberer (String language) {
Numberer numberer;
if (language.equals("en")) {
numberer = defaultNumberer;
} else {
String langClassName = "net.sf.saxon.number.Numberer_";
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy