summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Burdess <dog@bluezoo.org>2006-01-12 16:35:51 +0000
committerChris Burdess <dog@bluezoo.org>2006-01-12 16:35:51 +0000
commit27affa71c21beb8d5c7c9e981bf5fce0576c08f5 (patch)
tree0aa3d799f88964ac3fe3f6f53663ae16fc33cde9
parent7b8e31bd1ed72a57e58388dfcd59ce3ae85d4c99 (diff)
downloadclasspath-27affa71c21beb8d5c7c9e981bf5fce0576c08f5.tar.gz
2006-01-12 Chris Burdess <dog@gnu.org>
* gnu/xml/dom/DomDocument.java, gnu/xml/dom/DomElement.java, gnu/xml/dom/DomNode.java, gnu/xml/stream/XMLParser.java, gnu/xml/transform/Bindings.java, gnu/xml/transform/ElementAvailableFunction.java, gnu/xml/transform/ElementNode.java, gnu/xml/transform/FunctionAvailableFunction.java, gnu/xml/transform/NamespaceProxy.java, gnu/xml/transform/StreamSerializer.java, gnu/xml/transform/Stylesheet.java, gnu/xml/transform/TransformerImpl.java, gnu/xml/xpath/Selector.java: Implement isEqualNode correctly for document and element nodes; correct coalescing semantics when parsing; attribute-sets can only refer to top-level variables and parameters; fix namespace retrieval during element-available and function-available functions; implement xsl:fallback for extension elements; tokenize whitespace correctly during whitespace stripping; correct following and previous node axes selectors.
-rw-r--r--ChangeLog22
-rw-r--r--gnu/xml/dom/DomDocument.java25
-rw-r--r--gnu/xml/dom/DomElement.java33
-rw-r--r--gnu/xml/dom/DomNode.java80
-rw-r--r--gnu/xml/stream/XMLParser.java22
-rw-r--r--gnu/xml/transform/Bindings.java22
-rw-r--r--gnu/xml/transform/ElementAvailableFunction.java20
-rw-r--r--gnu/xml/transform/ElementNode.java2
-rw-r--r--gnu/xml/transform/FunctionAvailableFunction.java28
-rw-r--r--gnu/xml/transform/NamespaceProxy.java77
-rw-r--r--gnu/xml/transform/StreamSerializer.java10
-rw-r--r--gnu/xml/transform/Stylesheet.java18
-rw-r--r--gnu/xml/transform/TransformerImpl.java59
-rw-r--r--gnu/xml/xpath/Selector.java129
14 files changed, 374 insertions, 173 deletions
diff --git a/ChangeLog b/ChangeLog
index 42f4f8467..cb01bc22e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2006-01-12 Chris Burdess <dog@gnu.org>
+
+ * gnu/xml/dom/DomDocument.java,
+ gnu/xml/dom/DomElement.java,
+ gnu/xml/dom/DomNode.java,
+ gnu/xml/stream/XMLParser.java,
+ gnu/xml/transform/Bindings.java,
+ gnu/xml/transform/ElementAvailableFunction.java,
+ gnu/xml/transform/ElementNode.java,
+ gnu/xml/transform/FunctionAvailableFunction.java,
+ gnu/xml/transform/NamespaceProxy.java,
+ gnu/xml/transform/StreamSerializer.java,
+ gnu/xml/transform/Stylesheet.java,
+ gnu/xml/transform/TransformerImpl.java,
+ gnu/xml/xpath/Selector.java: Implement isEqualNode correctly for
+ document and element nodes; correct coalescing semantics when parsing;
+ attribute-sets can only refer to top-level variables and parameters;
+ fix namespace retrieval during element-available and
+ function-available functions; implement xsl:fallback for extension
+ elements; tokenize whitespace correctly during whitespace stripping;
+ correct following and previous node axes selectors.
+
2006-01-12 Roman Kennke <kennke@aicas.com>
* java/util/Hashtable.java
diff --git a/gnu/xml/dom/DomDocument.java b/gnu/xml/dom/DomDocument.java
index 29b8dc72e..900d03ac3 100644
--- a/gnu/xml/dom/DomDocument.java
+++ b/gnu/xml/dom/DomDocument.java
@@ -1313,6 +1313,31 @@ public class DomDocument
return config;
}
+ public boolean isEqualNode(Node arg)
+ {
+ if (!super.isEqualNode(arg))
+ return false;
+ Document d = (Document) arg;
+ String dversion = d.getXmlVersion();
+ if (dversion == null || !dversion.equals(version))
+ return false;
+ boolean dstandalone = d.getXmlStandalone();
+ if (dstandalone != standalone)
+ return false;
+ String dencoding = d.getXmlEncoding();
+ if (dencoding == null || dencoding.equalsIgnoreCase("UTF-8"))
+ {
+ if (encoding != null && !encoding.equalsIgnoreCase("UTF-8"))
+ return false;
+ }
+ else
+ {
+ if (!dencoding.equals(encoding))
+ return false;
+ }
+ return true;
+ }
+
public void normalizeDocument()
{
boolean save = building;
diff --git a/gnu/xml/dom/DomElement.java b/gnu/xml/dom/DomElement.java
index 34509f647..f55b084cc 100644
--- a/gnu/xml/dom/DomElement.java
+++ b/gnu/xml/dom/DomElement.java
@@ -519,5 +519,38 @@ public class DomElement
Attr attr = (Attr) attrs.getNamedItemNS(namespaceURI, localName);
setIdAttributeNode(attr, isId);
}
+
+ public boolean isEqualNode(Node arg)
+ {
+ if (!super.isEqualNode(arg))
+ return false;
+ getAttributes();
+ NamedNodeMap argAttrs = arg.getAttributes();
+ int len = argAttrs.getLength();
+ if (argAttrs == null || (len != attributes.length))
+ return false;
+ for (int i = 0; i < len; i++)
+ {
+ Node argCtx = argAttrs.item(i);
+ // Don't compare namespace nodes
+ if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
+ .equals(argCtx.getNamespaceURI()))
+ continue;
+ // Find corresponding attribute node
+ DomNode ctx = attributes.first;
+ for (; ctx != null; ctx = ctx.next)
+ {
+ if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI
+ .equals(ctx.getNamespaceURI()))
+ continue;
+ if (!ctx.isEqualNode(argCtx))
+ continue;
+ break;
+ }
+ if (ctx == null)
+ return false; // not found
+ }
+ return true;
+ }
}
diff --git a/gnu/xml/dom/DomNode.java b/gnu/xml/dom/DomNode.java
index 5cd5be269..68a2582b7 100644
--- a/gnu/xml/dom/DomNode.java
+++ b/gnu/xml/dom/DomNode.java
@@ -1749,7 +1749,10 @@ public abstract class DomNode
switch (ctx.nodeType)
{
case TEXT_NODE:
- while (ctx.next != null && ctx.next.nodeType == TEXT_NODE)
+ case CDATA_SECTION_NODE:
+ while (ctx.next != null &&
+ (ctx.next.nodeType == TEXT_NODE ||
+ ctx.next.nodeType == CDATA_SECTION_NODE))
{
Text text = (Text) ctx;
text.appendData(ctx.next.getNodeValue());
@@ -1988,40 +1991,64 @@ public abstract class DomNode
public boolean isEqualNode(Node arg)
{
+ boolean ret = isEqualNode2(arg);
+ System.err.println("isEqualNode("+toString()+","+arg.toString()+")="+ret);
+ return ret;
+ }
+
+ public boolean isEqualNode2(Node arg)
+ {
if (this == arg)
- {
- return true;
- }
+ return true;
if (arg == null)
+ return false;
+ if (nodeType != arg.getNodeType())
+ return false;
+ switch (nodeType)
{
- return false;
- }
- if (nodeType != arg.getNodeType() ||
- !equal(getNodeName(), arg.getNodeName()) ||
- !equal(getLocalName(), arg.getLocalName()) ||
- !equal(getNamespaceURI(), arg.getNamespaceURI()) ||
- !equal(getPrefix(), arg.getPrefix()) ||
- !equal(getNodeValue(), arg.getNodeValue()))
- {
- return false;
+ case ELEMENT_NODE:
+ case ATTRIBUTE_NODE:
+ if (!equal(getLocalName(), arg.getLocalName()) ||
+ !equal(getNamespaceURI(), arg.getNamespaceURI()))
+ return false;
+ break;
+ case PROCESSING_INSTRUCTION_NODE:
+ if (!equal(getNodeName(), arg.getNodeName()) ||
+ !equal(getNodeValue(), arg.getNodeValue()))
+ return false;
+ break;
+ case COMMENT_NODE:
+ case TEXT_NODE:
+ case CDATA_SECTION_NODE:
+ if (!equal(getNodeValue(), arg.getNodeValue()))
+ return false;
+ break;
}
// Children
Node argCtx = arg.getFirstChild();
getFirstChild(); // because of DomAttr lazy children
- for (DomNode ctx = first; ctx != null; ctx = ctx.next)
+ DomNode ctx = first;
+ for (; ctx != null && argCtx != null; ctx = ctx.next)
{
- if (!ctx.isEqualNode(argCtx))
+ if (nodeType == DOCUMENT_NODE)
{
- return false;
+ // Ignore whitespace outside document element
+ while (ctx != null && ctx.nodeType == TEXT_NODE)
+ ctx = ctx.next;
+ while (argCtx != null && ctx.getNodeType() == TEXT_NODE)
+ argCtx = argCtx.getNextSibling();
+ if (ctx == null && argCtx != null)
+ return false;
+ else if (argCtx == null && ctx != null)
+ return false;
}
+ if (!ctx.isEqualNode(argCtx))
+ return false;
argCtx = argCtx.getNextSibling();
}
- if (argCtx != null)
- {
- return false;
- }
+ if (ctx != null || argCtx != null)
+ return false;
- // TODO Attr NamedNodeMap
// TODO DocumentType
return true;
}
@@ -2157,5 +2184,14 @@ public abstract class DomNode
}
}
+ public void list(java.io.PrintStream out, int indent)
+ {
+ for (int i = 0; i < indent; i++)
+ out.print(" ");
+ out.println(toString());
+ for (DomNode ctx = first; ctx != null; ctx = ctx.next)
+ ctx.list(out, indent + 1);
+ }
+
}
diff --git a/gnu/xml/stream/XMLParser.java b/gnu/xml/stream/XMLParser.java
index f856f9372..4240d8590 100644
--- a/gnu/xml/stream/XMLParser.java
+++ b/gnu/xml/stream/XMLParser.java
@@ -282,8 +282,8 @@ public class XMLParser
private final boolean stringInterning;
/**
- * If true, adjacent text will always be reported as one event.
- * Otherwise multiple text events (chunks) may be reported.
+ * If true, CDATA sections will be merged with adjacent text nodes into a
+ * single event.
*/
private final boolean coalescing;
@@ -366,8 +366,8 @@ public class XMLParser
* (necessary if there are external entities to be resolved)
* @param validating if the parser is to be a validating parser
* @param namespaceAware if the parser should support XML Namespaces
- * @param coalescing if text should be reported as a single event instead
- * of a series of events
+ * @param coalescing if CDATA sections should be merged into adjacent text
+ * nodes
* @param replaceERefs if entity references should be automatically
* replaced by their replacement text (otherwise they will be reported as
* entity-reference events)
@@ -423,8 +423,8 @@ public class XMLParser
* (necessary if there are external entities to be resolved)
* @param validating if the parser is to be a validating parser
* @param namespaceAware if the parser should support XML Namespaces
- * @param coalescing if text should be reported as a single event instead
- * of a series of events
+ * @param coalescing if CDATA sections should be merged into adjacent text
+ * nodes
* @param replaceERefs if entity references should be automatically
* replaced by their replacement text (otherwise they will be reported as
* entity-reference events)
@@ -3088,8 +3088,12 @@ public class XMLParser
case 0x3c: // '<'
reset();
read(tmpBuf, 0, i);
- done = true;
- break; // end of text sequence
+ i = len;
+ if (coalescing && tryRead(TEST_CDATA))
+ readUntil(TEST_END_CDATA); // read CDATA section into buf
+ else
+ done = true; // end of text sequence
+ break;
default:
if (input.xml11)
{
@@ -3106,7 +3110,7 @@ public class XMLParser
}
// if text buffer >= 2MB, return it as a chunk
// to avoid excessive memory use
- if (!coalescing && buf.length() >= 2097152)
+ if (buf.length() >= 2097152)
done = true;
}
if (entities)
diff --git a/gnu/xml/transform/Bindings.java b/gnu/xml/transform/Bindings.java
index c372ea830..4ee083223 100644
--- a/gnu/xml/transform/Bindings.java
+++ b/gnu/xml/transform/Bindings.java
@@ -78,6 +78,11 @@ public class Bindings
*/
final LinkedList withParameters;
+ /**
+ * Only search globals.
+ */
+ boolean global;
+
Bindings(Stylesheet stylesheet)
{
this.stylesheet = stylesheet;
@@ -136,6 +141,12 @@ public class Bindings
public boolean containsKey(QName name, int type)
{
+ if (global)
+ {
+ Map ctx1 = (Map) variables.getLast();
+ Map ctx2 = (Map) parameters.getLast();
+ return (ctx1.containsKey(name) || ctx2.containsKey(name));
+ }
Iterator i = null;
switch (type)
{
@@ -165,6 +176,17 @@ public class Bindings
public Object get(QName name, Node context, int pos, int len)
{
+ if (global)
+ {
+ Map ctx = (Map) variables.getLast();
+ Object ret = ctx.get(name);
+ if (ret == null)
+ {
+ ctx = (Map) parameters.getLast();
+ ret = ctx.get(name);
+ }
+ return ret;
+ }
//System.err.println("bindings.get: "+name);
//System.err.println("\t"+toString());
Object ret = null;
diff --git a/gnu/xml/transform/ElementAvailableFunction.java b/gnu/xml/transform/ElementAvailableFunction.java
index 84cb6207a..0385a2e7e 100644
--- a/gnu/xml/transform/ElementAvailableFunction.java
+++ b/gnu/xml/transform/ElementAvailableFunction.java
@@ -140,12 +140,13 @@ class ElementAvailableFunction
localName = name.substring(ci + 1);
}
uri = nsctx.getNamespaceURI(prefix);
+ System.err.println("**** element-avaliable: prefix="+prefix+" uri="+uri);
if (Stylesheet.XSL_NS.equals(uri))
{
return elements.contains(localName) ?
Boolean.TRUE : Boolean.FALSE;
- // TODO extension elements
}
+ // TODO extension elements
return Boolean.FALSE;
}
@@ -153,16 +154,12 @@ class ElementAvailableFunction
{
NamespaceContext n = nsctx;
if (context instanceof NamespaceContext)
- {
- n = (NamespaceContext) context;
- }
+ n = (NamespaceContext) context;
ElementAvailableFunction f = new ElementAvailableFunction(n);
int len = args.size();
List args2 = new ArrayList(len);
for (int i = 0; i < len; i++)
- {
- args2.add(((Expr) args.get(i)).clone(context));
- }
+ args2.add(((Expr) args.get(i)).clone(context));
f.setArguments(args2);
return f;
}
@@ -172,12 +169,15 @@ class ElementAvailableFunction
for (Iterator i = args.iterator(); i.hasNext(); )
{
if (((Expr) i.next()).references(var))
- {
- return true;
- }
+ return true;
}
return false;
}
+ public String toString()
+ {
+ return "element-available(" + args.get(0) + ")";
+ }
+
}
diff --git a/gnu/xml/transform/ElementNode.java b/gnu/xml/transform/ElementNode.java
index 35a3c3ffd..092c56a4b 100644
--- a/gnu/xml/transform/ElementNode.java
+++ b/gnu/xml/transform/ElementNode.java
@@ -206,6 +206,7 @@ final class ElementNode
Node parent, Node nextSibling, String attributeSet)
throws TransformerException
{
+ stylesheet.bindings.global = true;
for (Iterator i = stylesheet.attributeSets.iterator(); i.hasNext(); )
{
AttributeSet as = (AttributeSet) i.next();
@@ -223,6 +224,7 @@ final class ElementNode
context, pos, len,
parent, nextSibling);
}
+ stylesheet.bindings.global = false;
}
public boolean references(QName var)
diff --git a/gnu/xml/transform/FunctionAvailableFunction.java b/gnu/xml/transform/FunctionAvailableFunction.java
index 7daf7ea3f..ab86401d0 100644
--- a/gnu/xml/transform/FunctionAvailableFunction.java
+++ b/gnu/xml/transform/FunctionAvailableFunction.java
@@ -147,11 +147,16 @@ class FunctionAvailableFunction
uri = nsctx.getNamespaceURI(prefix);
if (uri == null)
{
- return xsltFunctions.contains(localName) ||
- xpathFunctions.contains(localName) ?
+ return (xpathFunctions.contains(localName) ||
+ xsltFunctions.contains(localName)) ?
Boolean.TRUE : Boolean.FALSE;
- // TODO extension functions
}
+ else if (Stylesheet.XSL_NS.equals(uri))
+ {
+ return xsltFunctions.contains(localName) ?
+ Boolean.TRUE : Boolean.FALSE;
+ }
+ // TODO extension functions
return Boolean.FALSE;
}
@@ -159,16 +164,12 @@ class FunctionAvailableFunction
{
NamespaceContext n = nsctx;
if (context instanceof NamespaceContext)
- {
- n = (NamespaceContext) context;
- }
+ n = (NamespaceContext) context;
FunctionAvailableFunction f = new FunctionAvailableFunction(n);
int len = args.size();
List args2 = new ArrayList(len);
for (int i = 0; i < len; i++)
- {
- args2.add(((Expr) args.get(i)).clone(context));
- }
+ args2.add(((Expr) args.get(i)).clone(context));
f.setArguments(args2);
return f;
}
@@ -178,12 +179,15 @@ class FunctionAvailableFunction
for (Iterator i = args.iterator(); i.hasNext(); )
{
if (((Expr) i.next()).references(var))
- {
- return true;
- }
+ return true;
}
return false;
}
+ public String toString()
+ {
+ return "function-available(" + args.get(0) + ")";
+ }
+
}
diff --git a/gnu/xml/transform/NamespaceProxy.java b/gnu/xml/transform/NamespaceProxy.java
new file mode 100644
index 000000000..b3c233cd7
--- /dev/null
+++ b/gnu/xml/transform/NamespaceProxy.java
@@ -0,0 +1,77 @@
+/* NamespaceProxy.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.xml.transform;
+
+import java.util.Collections;
+import java.util.Iterator;
+import javax.xml.namespace.NamespaceContext;
+import org.w3c.dom.Node;
+
+/**
+ * A namespace context using a DOM node to resolve the namespace.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ */
+class NamespaceProxy
+ implements NamespaceContext
+{
+
+ private final Node node;
+
+ NamespaceProxy(Node node)
+ {
+ this.node = node;
+ }
+
+ public String getNamespaceURI(String prefix)
+ {
+ return (node == null) ? null : node.lookupNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI)
+ {
+ return (node == null) ? null : node.lookupPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(String namespaceURI)
+ {
+ // TODO
+ return Collections.singleton(getPrefix(namespaceURI)).iterator();
+ }
+
+}
diff --git a/gnu/xml/transform/StreamSerializer.java b/gnu/xml/transform/StreamSerializer.java
index 44e17fe3f..fb8b1a601 100644
--- a/gnu/xml/transform/StreamSerializer.java
+++ b/gnu/xml/transform/StreamSerializer.java
@@ -371,18 +371,18 @@ public class StreamSerializer
version = "1.0";
out.write(BRA);
out.write(0x3f);
- out.write("xml version='".getBytes("US-ASCII"));
+ out.write("xml version=\"".getBytes("US-ASCII"));
out.write(version.getBytes("US-ASCII"));
- out.write(APOS);
+ out.write(0x22);
if (!("UTF-8".equalsIgnoreCase(encoding)))
{
- out.write(" encoding='".getBytes("US-ASCII"));
+ out.write(" encoding=\"".getBytes("US-ASCII"));
out.write(encoding.getBytes("US-ASCII"));
- out.write(APOS);
+ out.write(0x22);
}
if ((doc != null && doc.getXmlStandalone()) ||
"yes".equals(node.getUserData("standalone")))
- out.write(" standalone='yes'".getBytes("US-ASCII"));
+ out.write(" standalone=\"yes\"".getBytes("US-ASCII"));
out.write(0x3f);
out.write(KET);
out.write(encodeText(eol));
diff --git a/gnu/xml/transform/Stylesheet.java b/gnu/xml/transform/Stylesheet.java
index e20bef288..51accaa3b 100644
--- a/gnu/xml/transform/Stylesheet.java
+++ b/gnu/xml/transform/Stylesheet.java
@@ -1077,9 +1077,9 @@ class Stylesheet
else if ("system-property".equals(localName) && (arity == 1))
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;
}
@@ -1498,7 +1498,19 @@ 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())
diff --git a/gnu/xml/transform/TransformerImpl.java b/gnu/xml/transform/TransformerImpl.java
index ef49a22d3..b7ff66884 100644
--- a/gnu/xml/transform/TransformerImpl.java
+++ b/gnu/xml/transform/TransformerImpl.java
@@ -47,7 +47,6 @@ import java.net.MalformedURLException;
import java.net.UnknownServiceException;
import java.net.URL;
import java.net.URLConnection;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
@@ -461,40 +460,42 @@ class TransformerImpl
*/
private static String[] tokenizeWhitespace(String text)
{
- List acc = new ArrayList();
- StringBuffer buf = new StringBuffer();
- int state = 0; // 0=NONE 1=SPACE 2=TEXT
int len = text.length();
+ int start = 0, end = len - 1;
+ // Find index of text start
for (int i = 0; i < len; i++)
{
char c = text.charAt(i);
boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r');
- switch (state)
- {
- case 1: // SPACE
- if (!whitespace)
- {
- acc.add(buf.toString());
- buf.setLength(0);
- state = 2;
- }
- break;
- case 2: // TEXT
- if (whitespace)
- {
- acc.add(buf.toString());
- buf.setLength(0);
- state = 1;
- }
- break;
- case 0: // NONE
- state = whitespace ? 1 : 2;
- break;
- }
- buf.append(c);
+ if (whitespace)
+ start++;
+ else
+ break;
+ }
+ if (start == end) // all whitespace
+ return new String[] { text };
+ // Find index of text end
+ for (int i = end; i > start; i--)
+ {
+ char c = text.charAt(i);
+ boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r');
+ if (whitespace)
+ end--;
+ else
+ break;
}
- acc.add(buf.toString());
- return (String[]) acc.toArray(new String[acc.size()]);
+ if (start == 0 && end == len - 1) // all non-whitespace
+ return new String[] { text };
+ // whitespace, then text, then whitespace
+ String[] ret = (start > 0 && end < len - 1) ?
+ new String[3] : new String[2];
+ int i = 0;
+ if (start > 0)
+ ret[i++] = text.substring(0, start);
+ ret[i++] = text.substring(start, end + 1);
+ if (end < len - 1)
+ ret[i++] = text.substring(end + 1);
+ return ret;
}
/**
diff --git a/gnu/xml/xpath/Selector.java b/gnu/xml/xpath/Selector.java
index 598038064..ebaeb28fc 100644
--- a/gnu/xml/xpath/Selector.java
+++ b/gnu/xml/xpath/Selector.java
@@ -1,5 +1,5 @@
/* Selector.java --
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004,2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -111,16 +111,12 @@ public final class Selector
{
case CHILD:
if (nodeType == Node.ATTRIBUTE_NODE)
- {
- return false;
- }
+ return false;
break;
case ATTRIBUTE:
case NAMESPACE:
if (nodeType != Node.ATTRIBUTE_NODE)
- {
- return false;
- }
+ return false;
break;
case DESCENDANT_OR_SELF:
return true;
@@ -136,9 +132,7 @@ public final class Selector
{
Test test = tests[j];
if (!test.matches(context, pos, len))
- {
- return false;
- }
+ return false;
}
}
return true;
@@ -149,9 +143,7 @@ public final class Selector
int pos = 1;
for (ctx = ctx.getPreviousSibling(); ctx != null;
ctx = ctx.getPreviousSibling())
- {
- pos++;
- }
+ pos++;
return pos;
}
@@ -164,9 +156,7 @@ public final class Selector
}
Node parent = ctx.getParentNode();
if (parent != null)
- {
- return parent.getChildNodes().getLength();
- }
+ return parent.getChildNodes().getLength();
return 1;
}
@@ -175,7 +165,6 @@ public final class Selector
Set acc = new LinkedHashSet();
addCandidates(context, acc);
List candidates = new ArrayList(acc);
- //Collections.sort(candidates, documentOrderComparator);
List ret = filterCandidates(candidates, false);
return ret;
}
@@ -184,11 +173,8 @@ public final class Selector
{
Set acc = new LinkedHashSet();
for (Iterator i = ns.iterator(); i.hasNext(); )
- {
- addCandidates((Node) i.next(), acc);
- }
+ addCandidates((Node) i.next(), acc);
List candidates = new ArrayList(acc);
- //Collections.sort(candidates, documentOrderComparator);
List ret = filterCandidates(candidates, true);
return ret;
}
@@ -230,17 +216,7 @@ public final class Selector
}
}
if (test.matches(node, i + 1, len))
- {
- successful.add(node);
- }
- /*
- System.err.println("Testing "+node);
- int p = getContextPosition(node);
- int l = getContextSize(node);
- if (test.matches(node, p, l))
- {
- successful.add(node);
- }*/
+ successful.add(node);
}
candidates = successful;
len = candidates.size();
@@ -305,9 +281,7 @@ public final class Selector
{
acc.add(child);
if (recurse)
- {
- addChildNodes(child, acc, recurse);
- }
+ addChildNodes(child, acc, recurse);
child = child.getNextSibling();
}
}
@@ -320,55 +294,62 @@ public final class Selector
{
acc.add(parent);
if (recurse)
- {
- addParentNode(parent, acc, recurse);
- }
+ addParentNode(parent, acc, recurse);
}
}
void addFollowingNodes(Node context, Collection acc, boolean recurse)
{
- Node cur = context.getNextSibling();
+ if (context != null && recurse)
+ addChildNodes(context, acc, true);
+ Node cur = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? null :
+ context.getNextSibling();
while (cur != null)
{
acc.add(cur);
if (recurse)
- {
- addChildNodes(cur, acc, true);
- }
+ addChildNodes(cur, acc, true);
cur = cur.getNextSibling();
}
if (recurse)
{
- context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
- ((Attr) context).getOwnerElement() : context.getParentNode();
- if (context != null)
+ while (context != null)
{
- addFollowingNodes(context, acc, recurse);
+ context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
+ ((Attr) context).getOwnerElement() : context.getParentNode();
+ if (context != null)
+ {
+ cur = context.getNextSibling();
+ while (cur != null)
+ {
+ acc.add(cur);
+ if (recurse)
+ addChildNodes(cur, acc, true);
+ cur = cur.getNextSibling();
+ }
+ }
}
}
}
void addPrecedingNodes(Node context, Collection acc, boolean recurse)
{
- Node cur = context.getPreviousSibling();
+ Node cur = (context.getNodeType() == Node.ATTRIBUTE_NODE) ? null :
+ context.getPreviousSibling();
while (cur != null)
{
acc.add(cur);
if (recurse)
- {
- addChildNodes(cur, acc, true);
- }
+ addChildNodes(cur, acc, true);
cur = cur.getPreviousSibling();
}
if (recurse)
{
- context = (context.getNodeType() == Node.ATTRIBUTE_NODE) ?
- ((Attr) context).getOwnerElement() : context.getParentNode();
- if (context != null)
- {
- addPrecedingNodes(context, acc, recurse);
- }
+ cur = context;
+ cur = (cur.getNodeType() == Node.ATTRIBUTE_NODE) ?
+ ((Attr) cur).getOwnerElement() : cur.getParentNode();
+ if (cur != null)
+ addPrecedingNodes(cur, acc, recurse);
}
}
@@ -399,9 +380,7 @@ public final class Selector
{
Node attr = attrs.item(i);
if (isNamespaceAttribute(attr))
- {
- acc.add(attr);
- }
+ acc.add(attr);
}
}
}
@@ -419,9 +398,7 @@ public final class Selector
int len = tests.length;
List tests2 = new ArrayList(len);
for (int i = 0; i < len; i++)
- {
- tests2.add(tests[i].clone(context));
- }
+ tests2.add(tests[i].clone(context));
return new Selector(axis, tests2);
}
@@ -430,9 +407,7 @@ public final class Selector
for (int i = 0; i < tests.length; i++)
{
if (tests[i].references(var))
- {
- return true;
- }
+ return true;
}
return false;
}
@@ -451,13 +426,9 @@ public final class Selector
case ATTRIBUTE:
if (tests.length == 0 ||
(tests[0] instanceof NameTest))
- {
- buf.append('@');
- }
+ buf.append('@');
else
- {
- buf.append("attribute::");
- }
+ buf.append("attribute::");
break;
case CHILD:
//buf.append("child::");
@@ -481,9 +452,7 @@ public final class Selector
if (tests.length == 0 ||
(tests[0] instanceof NodeTypeTest &&
((NodeTypeTest) tests[0]).type == 0))
- {
- return "..";
- }
+ return "..";
buf.append("parent::");
break;
case PRECEDING:
@@ -496,22 +465,16 @@ public final class Selector
if (tests.length == 0 ||
(tests[0] instanceof NodeTypeTest &&
((NodeTypeTest) tests[0]).type == 0))
- {
- return ".";
- }
+ return ".";
buf.append("self::");
break;
}
if (tests.length == 0)
- {
- buf.append('*');
- }
+ buf.append('*');
else
{
for (int i = 0; i < tests.length; i++)
- {
- buf.append(tests[i]);
- }
+ buf.append(tests[i]);
}
return buf.toString();
}