summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/xml/transform/Stylesheet.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/xml/transform/Stylesheet.java')
-rw-r--r--libjava/classpath/gnu/xml/transform/Stylesheet.java375
1 files changed, 150 insertions, 225 deletions
diff --git a/libjava/classpath/gnu/xml/transform/Stylesheet.java b/libjava/classpath/gnu/xml/transform/Stylesheet.java
index 99431b699d8..51accaa3b9a 100644
--- a/libjava/classpath/gnu/xml/transform/Stylesheet.java
+++ b/libjava/classpath/gnu/xml/transform/Stylesheet.java
@@ -1,5 +1,5 @@
/* Stylesheet.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004,2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -88,6 +88,8 @@ class Stylesheet
{
static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform";
+ private static final NameTest STYLESHEET_PRESERVE_TEXT =
+ new NameTest(new QName(XSL_NS, "text"), false, false);
static final int OUTPUT_XML = 0;
static final int OUTPUT_HTML = 1;
@@ -208,6 +210,7 @@ class Stylesheet
preserveSpace = new LinkedHashSet();
outputCdataSectionElements = new LinkedHashSet();
xpath = (XPathImpl) factory.xpathFactory.newXPath();
+ xpath.setNamespaceContext(this);
if (parent == null)
{
bindings = new Bindings(this);
@@ -218,7 +221,6 @@ class Stylesheet
keys = new LinkedList();
decimalFormats = new LinkedHashMap();
initDefaultDecimalFormat();
- xpath.setNamespaceContext(this);
xpath.setXPathFunctionResolver(this);
}
else
@@ -241,7 +243,6 @@ class Stylesheet
templates = root.templates;
keys = root.keys;
decimalFormats = root.decimalFormats;
- xpath.setNamespaceContext(root);
xpath.setXPathFunctionResolver(root);
}
xpath.setXPathVariableResolver(bindings);
@@ -276,9 +277,7 @@ class Stylesheet
{
Stylesheet stylesheet = this;
while (stylesheet.parent != null)
- {
- stylesheet = stylesheet.parent;
- }
+ stylesheet = stylesheet.parent;
return stylesheet;
}
@@ -408,9 +407,7 @@ class Stylesheet
throws TransformerException
{
if (debug)
- {
- System.err.println("getTemplate: mode="+mode+" context="+context);
- }
+ System.err.println("getTemplate: mode="+mode+" context="+context);
Set candidates = new TreeSet();
for (Iterator j = templates.iterator(); j.hasNext(); )
{
@@ -425,15 +422,11 @@ class Stylesheet
throw new TransformerException(msg);
}
if (!currentTemplate.imports(t))
- {
- isMatch = false;
- }
+ isMatch = false;
}
//System.err.println("\t"+context+" "+t+"="+isMatch);
if (isMatch)
- {
- candidates.add(t);
- }
+ candidates.add(t);
}
//System.err.println("\tcandidates="+candidates);
if (candidates.isEmpty())
@@ -441,9 +434,7 @@ class Stylesheet
// Apply built-in template
// Current template is unchanged
if (debug)
- {
- System.err.println("\tbuiltInTemplate context="+context);
- }
+ System.err.println("\tbuiltInTemplate context="+context);
switch (context.getNodeType())
{
case Node.ELEMENT_NODE:
@@ -453,6 +444,7 @@ class Stylesheet
case Node.COMMENT_NODE:
return builtInNodeTemplate;
case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
case Node.ATTRIBUTE_NODE:
return builtInTextTemplate;
default:
@@ -465,9 +457,7 @@ class Stylesheet
// Set current template
currentTemplate = t;
if (debug)
- {
- System.err.println("\ttemplate="+t+" context="+context);
- }
+ System.err.println("\ttemplate="+t+" context="+context);
return t.node;
}
}
@@ -475,25 +465,17 @@ class Stylesheet
TemplateNode getTemplate(QName mode, QName name)
throws TransformerException
{
- //System.err.println("getTemplate: mode="+mode+" name="+name);
Set candidates = new TreeSet();
for (Iterator j = templates.iterator(); j.hasNext(); )
{
Template t = (Template) j.next();
boolean isMatch = t.matches(name);
- //System.err.println("\t"+name+" "+t+"="+isMatch);
if (isMatch)
- {
- candidates.add(t);
- }
+ candidates.add(t);
}
if (candidates.isEmpty())
- {
- return null;
- //throw new TransformerException("template '" + name + "' not found");
- }
+ return null;
Template t = (Template) candidates.iterator().next();
- //System.err.println("\ttemplate="+t+" context="+context);
return t.node;
}
@@ -538,42 +520,30 @@ class Stylesheet
output = node;
String method = getAttribute(attrs, "method");
if ("xml".equals(method) || method == null)
- {
- outputMethod = OUTPUT_XML;
- }
+ outputMethod = OUTPUT_XML;
else if ("html".equals(method))
- {
- outputMethod = OUTPUT_HTML;
- }
+ outputMethod = OUTPUT_HTML;
else if ("text".equals(method))
- {
- outputMethod = OUTPUT_TEXT;
- }
+ outputMethod = OUTPUT_TEXT;
else
{
String msg = "unsupported output method: " + method;
DOMSourceLocator l = new DOMSourceLocator(node);
throw new TransformerConfigurationException(msg, l);
}
- outputPublicId = getAttribute(attrs, "public-id");
- outputSystemId = getAttribute(attrs, "system-id");
+ outputPublicId = getAttribute(attrs, "doctype-public");
+ outputSystemId = getAttribute(attrs, "doctype-system");
outputEncoding = getAttribute(attrs, "encoding");
String indent = getAttribute(attrs, "indent");
if (indent != null)
- {
- outputIndent = "yes".equals(indent);
- }
+ outputIndent = "yes".equals(indent);
outputVersion = getAttribute(attrs, "version");
String omitXmlDecl = getAttribute(attrs, "omit-xml-declaration");
if (omitXmlDecl != null)
- {
- outputOmitXmlDeclaration = "yes".equals(omitXmlDecl);
- }
+ outputOmitXmlDeclaration = "yes".equals(omitXmlDecl);
String standalone = getAttribute(attrs, "standalone");
if (standalone != null)
- {
- outputStandalone = "yes".equals(standalone);
- }
+ outputStandalone = "yes".equals(standalone);
outputMediaType = getAttribute(attrs, "media-type");
String cdataSectionElements =
getAttribute(attrs, "cdata-section-elements");
@@ -581,9 +551,7 @@ class Stylesheet
{
StringTokenizer st = new StringTokenizer(cdataSectionElements, " ");
while (st.hasMoreTokens())
- {
- outputCdataSectionElements.add(st.nextToken());
- }
+ outputCdataSectionElements.add(st.nextToken());
}
}
@@ -728,9 +696,7 @@ class Stylesheet
parse(node.getFirstChild(), false);
}
else if ("template".equals(name))
- {
- templates.add(parseTemplate(node, attrs));
- }
+ templates.add(parseTemplate(node, attrs));
else if ("param".equals(name) ||
"variable".equals(name))
{
@@ -779,9 +745,7 @@ class Stylesheet
factory.newStylesheet(source, precedence + delta, this);
}
else if ("output".equals(name))
- {
- parseOutput(node, attrs);
- }
+ parseOutput(node, attrs);
else if ("preserve-space".equals(name))
{
String elements =
@@ -790,7 +754,9 @@ class Stylesheet
" \t\n\r");
while (st.hasMoreTokens())
{
- preserveSpace.add(parseNameTest(st.nextToken()));
+ NameTest element = parseNameTest(st.nextToken());
+ preserveSpace.add(new StrippingInstruction(element,
+ precedence));
}
}
else if ("strip-space".equals(name))
@@ -801,25 +767,19 @@ class Stylesheet
" \t\n\r");
while (st.hasMoreTokens())
{
- stripSpace.add(parseNameTest(st.nextToken()));
+ NameTest element = parseNameTest(st.nextToken());
+ stripSpace.add(new StrippingInstruction(element,
+ precedence));
}
}
else if ("key".equals(name))
- {
- parseKey(node, attrs);
- }
+ parseKey(node, attrs);
else if ("decimal-format".equals(name))
- {
- parseDecimalFormat(node, attrs);
- }
+ parseDecimalFormat(node, attrs);
else if ("namespace-alias".equals(name))
- {
- parseNamespaceAlias(node, attrs);
- }
+ parseNamespaceAlias(node, attrs);
else if ("attribute-set".equals(name))
- {
- parseAttributeSet(node, attrs);
- }
+ parseAttributeSet(node, attrs);
}
else if (root)
{
@@ -867,12 +827,10 @@ class Stylesheet
final NameTest parseNameTest(String token)
{
if ("*".equals(token))
- {
- return new NameTest(null, true, true);
- }
+ return new NameTest(null, true, true);
else if (token.endsWith(":*"))
{
- QName qName = getQName(token.substring(0, token.length() - 2));
+ QName qName = getQName(token);
return new NameTest(qName, true, false);
}
else
@@ -984,7 +942,13 @@ class Stylesheet
return ret;
}
- boolean isPreserved(Text text)
+ /**
+ * Whitespace stripping.
+ * @param text the text node
+ * @param source true if a source node, false if a stylesheet text node
+ * @see http://www.w3.org/TR/xslt#strip
+ */
+ boolean isPreserved(Text text, boolean source)
throws TransformerConfigurationException
{
// Check characters in text
@@ -996,39 +960,73 @@ class Stylesheet
{
char c = value.charAt(i);
if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d)
- {
- return true;
- }
+ return true;
}
}
// Check parent node
Node ctx = text.getParentNode();
- if (!preserveSpace.isEmpty())
+ if (source)
{
- for (Iterator i = preserveSpace.iterator(); i.hasNext(); )
+ // Source document text node
+ boolean preserve = true;
+ float psPriority = 0.0f, ssPriority = 0.0f;
+ if (!stripSpace.isEmpty())
{
- NameTest preserveTest = (NameTest) i.next();
- if (preserveTest.matches(ctx, 1, 1))
+ // Conflict resolution
+ StrippingInstruction ssi = null, psi = null;
+ for (Iterator i = stripSpace.iterator(); i.hasNext(); )
+ {
+ StrippingInstruction si = (StrippingInstruction) i.next();
+ if (si.element.matches(ctx, 1, 1))
+ {
+ if (ssi != null)
+ {
+ if (si.precedence < ssi.precedence)
+ continue;
+ float p = si.getPriority();
+ if (p < ssPriority)
+ continue;
+ }
+ ssi = si;
+ }
+ }
+ for (Iterator i = preserveSpace.iterator(); i.hasNext(); )
{
- boolean override = false;
- if (!stripSpace.isEmpty())
+ StrippingInstruction si = (StrippingInstruction) i.next();
+ if (si.element.matches(ctx, 1, 1))
{
- for (Iterator j = stripSpace.iterator(); j.hasNext(); )
+ if (psi != null)
{
- NameTest stripTest = (NameTest) j.next();
- if (stripTest.matches(ctx, 1, 1))
- {
- override = true;
- break;
- }
+ if (si.precedence < psi.precedence)
+ continue;
+ float p = si.getPriority();
+ if (p < psPriority)
+ continue;
}
+ psi = si;
}
- if (!override)
+ }
+ if (ssi != null)
+ {
+ if (psi != null)
{
- return true;
+ if (psi.precedence < ssi.precedence)
+ preserve = false;
+ else if (psPriority < ssPriority)
+ preserve = false;
}
+ else
+ preserve = false;
}
}
+ if (preserve)
+ return true;
+ }
+ else
+ {
+ // Stylesheet text node
+ if (STYLESHEET_PRESERVE_TEXT.matches(ctx, 1, 1))
+ return true;
}
// Check whether any ancestor specified xml:space
while (ctx != null)
@@ -1038,24 +1036,14 @@ class Stylesheet
Element element = (Element) ctx;
String xmlSpace = element.getAttribute("xml:space");
if ("default".equals(xmlSpace))
- {
- break;
- }
+ break;
else if ("preserve".equals(xmlSpace))
- {
- return true;
- }
+ return true;
else if (xmlSpace.length() > 0)
{
String msg = "Illegal value for xml:space: " + xmlSpace;
throw new TransformerConfigurationException(msg);
}
- else if ("text".equals(ctx.getLocalName()) &&
- XSL_NS.equals(ctx.getNamespaceURI()))
- {
- // xsl:text implies xml:space='preserve'
- return true;
- }
}
ctx = ctx.getParentNode();
}
@@ -1071,45 +1059,27 @@ class Stylesheet
if ("document".equals(localName) && (arity == 1 || arity == 2))
{
if (current == null)
- {
throw new RuntimeException("current is null");
- }
return new DocumentFunction(getRootStylesheet(), current);
}
else if ("key".equals(localName) && (arity == 2))
- {
- return new KeyFunction(getRootStylesheet());
- }
+ return new KeyFunction(getRootStylesheet());
else if ("format-number".equals(localName) &&
(arity == 2 || arity == 3))
- {
- return new FormatNumberFunction(getRootStylesheet());
- }
+ return new FormatNumberFunction(getRootStylesheet());
else if ("current".equals(localName) && (arity == 0))
- {
- return new CurrentFunction(getRootStylesheet());
- }
+ return new CurrentFunction(getRootStylesheet());
else if ("unparsed-entity-uri".equals(localName) && (arity == 1))
- {
- return new UnparsedEntityUriFunction();
- }
+ return new UnparsedEntityUriFunction();
else if ("generate-id".equals(localName) &&
(arity == 1 || arity == 0))
- {
- return new GenerateIdFunction();
- }
+ return new GenerateIdFunction();
else if ("system-property".equals(localName) && (arity == 1))
- {
- return new SystemPropertyFunction();
- }
+ return new SystemPropertyFunction();
else if ("element-available".equals(localName) && (arity == 1))
- {
- return new ElementAvailableFunction(this);
- }
+ return new ElementAvailableFunction(new NamespaceProxy(current));
else if ("function-available".equals(localName) && (arity == 1))
- {
- return new FunctionAvailableFunction(this);
- }
+ return new FunctionAvailableFunction(new NamespaceProxy(current));
}
return null;
}
@@ -1127,9 +1097,7 @@ class Stylesheet
QName mode = (m == null) ? null : getQName(m);
String s = getAttribute(attrs, "select");
if (s == null)
- {
- s = "child::node()";
- }
+ s = "child::node()";
Node children = node.getFirstChild();
List sortKeys = parseSortKeys(children);
List withParams = parseWithParams(children);
@@ -1411,13 +1379,9 @@ class Stylesheet
if (tnode != null)
{
if (first == null)
- {
- first = tnode;
- }
+ first = tnode;
if (previous != null)
- {
- previous.next = tnode;
- }
+ previous.next = tnode;
previous = tnode;
}
node = next;
@@ -1438,25 +1402,15 @@ class Stylesheet
{
String name = node.getLocalName();
if ("apply-templates".equals(name))
- {
- return parseApplyTemplates(node);
- }
+ return parseApplyTemplates(node);
else if ("call-template".equals(name))
- {
- return parseCallTemplate(node);
- }
+ return parseCallTemplate(node);
else if ("value-of".equals(name))
- {
- return parseValueOf(node);
- }
+ return parseValueOf(node);
else if ("for-each".equals(name))
- {
- return parseForEach(node);
- }
+ return parseForEach(node);
else if ("if".equals(name))
- {
- return parseIf(node);
- }
+ return parseIf(node);
else if ("choose".equals(name))
{
Node children = node.getFirstChild();
@@ -1465,9 +1419,7 @@ class Stylesheet
return ret;
}
else if ("when".equals(name))
- {
- return parseWhen(node);
- }
+ return parseWhen(node);
else if ("otherwise".equals(name))
{
Node children = node.getFirstChild();
@@ -1476,25 +1428,15 @@ class Stylesheet
return ret;
}
else if ("element".equals(name))
- {
- return parseElement(node);
- }
+ return parseElement(node);
else if ("attribute".equals(name))
- {
- return parseAttribute(node);
- }
+ return parseAttribute(node);
else if ("text".equals(name))
- {
- return parseText(node);
- }
+ return parseText(node);
else if ("copy".equals(name))
- {
- return parseCopy(node);
- }
+ return parseCopy(node);
else if ("processing-instruction".equals(name))
- {
- return parseProcessingInstruction(node);
- }
+ return parseProcessingInstruction(node);
else if ("comment".equals(name))
{
Node children = node.getFirstChild();
@@ -1503,9 +1445,7 @@ class Stylesheet
return ret;
}
else if ("number".equals(name))
- {
- return parseNumber(node);
- }
+ return parseNumber(node);
else if ("param".equals(name) ||
"variable".equals(name))
{
@@ -1538,13 +1478,9 @@ class Stylesheet
return ret;
}
else if ("copy-of".equals(name))
- {
- return parseCopyOf(node);
- }
+ return parseCopyOf(node);
else if ("message".equals(name))
- {
- return parseMessage(node);
- }
+ return parseMessage(node);
else if ("apply-imports".equals(name))
{
Node children = node.getFirstChild();
@@ -1562,22 +1498,30 @@ class Stylesheet
String prefix = node.getPrefix();
if (extensionElementPrefixes.contains(prefix))
{
- // Pass over extension elements
+ // Check for xsl:fallback
+ for (Node ctx = node.getFirstChild(); ctx != null;
+ ctx = ctx.getNextSibling())
+ {
+ String ctxUri = ctx.getNamespaceURI();
+ if (XSL_NS.equals(ctxUri) &&
+ "fallback".equals(ctx.getLocalName()))
+ {
+ ctx = ctx.getFirstChild();
+ return (ctx == null) ? null : parse(ctx);
+ }
+ }
+ // Otherwise pass over extension element
return null;
}
switch (node.getNodeType())
{
case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
// Determine whether to strip whitespace
Text text = (Text) node;
- if (!isPreserved(text))
+ if (!isPreserved(text, false))
{
// Strip
- /*String data = text.getData().trim();
- if (data.length() > 0)
- {
- text.setData(data);
- } // else */
text.getParentNode().removeChild(text);
return null;
}
@@ -1623,9 +1567,7 @@ class Stylesheet
String aname = attr.getNodeName();
if (Stylesheet.XSL_NS.equals(ans) &&
"use-attribute-sets".equals(attr.getLocalName()))
- {
- continue;
- }
+ continue;
String value = attr.getNodeValue();
TemplateNode grandchild =
parseAttributeValueTemplate(value, node);
@@ -1640,8 +1582,9 @@ class Stylesheet
}
String ename = node.getNodeName();
TemplateNode n = parseAttributeValueTemplate(ename, node);
- TemplateNode ns = (namespaceUri == null) ? null :
- parseAttributeValueTemplate(namespaceUri, node);
+ //TemplateNode ns = (namespaceUri == null) ? null :
+ // parseAttributeValueTemplate(namespaceUri, node);
+ TemplateNode ns = null;
ElementNode ret = new ElementNode(n, ns, useAttributeSets,
node);
ret.children = child;
@@ -1676,9 +1619,7 @@ class Stylesheet
NamedNodeMap attrs = node.getAttributes();
String s = getAttribute(attrs, "select");
if (s == null)
- {
- s = ".";
- }
+ s = ".";
Expr select = (Expr) xpath.compile(s);
String l = getAttribute(attrs, "lang");
TemplateNode lang = (l == null) ? null :
@@ -1728,9 +1669,7 @@ class Stylesheet
ret.add(new WithParam(name, expr));
}
else
- {
- ret.add(new WithParam(name, content));
- }
+ ret.add(new WithParam(name, content));
}
node = node.getNextSibling();
}
@@ -1757,27 +1696,19 @@ class Stylesheet
{
String prefix = attr.getLocalName();
if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
- {
- prefix = "#default";
- }
+ prefix = "#default";
String ns = attr.getNodeValue();
// Should the namespace be excluded?
if (XSL_NS.equals(ns) ||
extensionElementPrefixes.contains(prefix) ||
elementExcludeResultPrefixes.contains(prefix) ||
excludeResultPrefixes.contains(prefix))
- {
- continue;
- }
+ continue;
// Is the namespace already defined on the target?
if (prefix == "#default")
- {
- prefix = null;
- }
+ prefix = null;
if (target.lookupNamespaceURI(prefix) != null)
- {
- continue;
- }
+ continue;
attr = attr.cloneNode(true);
attr = doc.adoptNode(attr);
target.getAttributes().setNamedItemNS(attr);
@@ -1786,23 +1717,17 @@ class Stylesheet
}
Node parent = source.getParentNode();
if (parent != null)
- {
- addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes);
- }
+ addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes);
}
static final String getAttribute(NamedNodeMap attrs, String name)
{
Node attr = attrs.getNamedItem(name);
if (attr == null)
- {
- return null;
- }
+ return null;
String ret = attr.getNodeValue();
if (ret.length() == 0)
- {
- return null;
- }
+ return null;
return ret;
}
OpenPOWER on IntegriCloud