xom-interest AT lists.ibiblio.org
Subject: XOM API for Processing XML with Java
List archive
Patched DocumentNavigator (was [XOM-interest] XPath support for XOM)
- From: Laurent Bihanic <laurent.bihanic AT atosorigin.com>
- To: XOM-interest <XOM-interest AT lists.ibiblio.org>
- Subject: Patched DocumentNavigator (was [XOM-interest] XPath support for XOM)
- Date: Fri, 07 Feb 2003 11:18:06 +0100
Hi,
Please find attached a patched version of DocumentNavigator (XPath support for XOM based on Jaxen) that fixes some potential namespace handling bug. I don't know what the actual bug effects are as it never appeared in my tests (I found the problem while reviewing the code).
Laurent
Laurent Bihanic wrote:
Hi,
Attached are 2 classes that add XPath support to XOM using the Jaxen path
engine (1.0 FCS). I ran quick tests including tests on XPath functions and
namespace support and so far everything seems OK.
I put these classes in a package nu.xom.xpath.jaxen thinking XOM should wrap
them into an engine-independent XPath class, the way JDOM does. Opinions?
Laurent
/*
*/
package nu.xom.xpath.jaxen;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import org.jaxen.XPath;
import org.jaxen.DefaultNavigator;
import org.jaxen.FunctionCallException;
import org.jaxen.util.SingleObjectIterator;
import org.saxpath.SAXPathException;
import nu.xom.Attribute;
import nu.xom.Comment;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Node;
import nu.xom.ParentNode;
import nu.xom.ProcessingInstruction;
import nu.xom.Text;
import nu.xom.Builder;
/**
* Class for navigating around the XOM object model.
* <p>
* This class is not intended for direct usage, but is used by the
* Jaxen engine during XPath expression evaluation.</p>
*/
public class DocumentNavigator extends DefaultNavigator {
/**
* Singleton implementation.
*/
private static class Singleton {
/**
* Singleton instance.
*/
private static DocumentNavigator instance = new DocumentNavigator();
}
public static DocumentNavigator getInstance() {
return Singleton.instance;
}
public boolean isElement(Object obj) {
return obj instanceof Element;
}
public boolean isComment(Object obj) {
return obj instanceof Comment;
}
public boolean isText(Object obj) {
return obj instanceof Text;
}
public boolean isAttribute(Object obj) {
return obj instanceof Attribute;
}
public boolean isProcessingInstruction(Object obj) {
return obj instanceof ProcessingInstruction;
}
public boolean isDocument(Object obj) {
return obj instanceof Document;
}
public boolean isNamespace(Object obj) {
return obj instanceof XPathNamespace;
}
public String getElementName(Object obj) {
return ((Element)obj).getLocalName();
}
public String getElementNamespaceUri(Object obj) {
String uri = ((Element)obj).getNamespaceURI();
return ((uri != null) && (uri.length() == 0))? null: uri;
}
public String getAttributeName(Object obj) {
return ((Attribute)obj).getLocalName();
}
public String getAttributeNamespaceUri(Object obj) {
String uri = ((Attribute)obj).getNamespaceURI();
return ((uri != null) && (uri.length() == 0))? null: uri;
}
public Iterator getChildAxisIterator(Object contextNode) {
if (contextNode instanceof ParentNode) {
ParentNode e = (ParentNode)contextNode;
int max = e.getChildCount();
List content = new ArrayList(max);
for (int i=0; i<max; i++) {
content.add(e.getChild(i));
}
return content.iterator();
}
return null;
}
public Iterator getNamespaceAxisIterator(Object contextNode) {
if (contextNode instanceof Element == false) {
return null;
}
Map nsMap = new HashMap();
Element context = (Element)contextNode;
Element current = context;
while (current != null) {
String prefix;
String uri = current.getNamespaceURI();
if (uri.length() != 0) {
prefix = current.getNamespacePrefix();
if (!nsMap.containsKey(prefix)) {
nsMap.put(prefix,
new XPathNamespace(context, prefix, uri));
}
}
int max = current.getNamespaceDeclarationCount();
for (int i=0; i<max; i++) {
prefix = current.getNamespacePrefix(i);
if (!nsMap.containsKey(prefix)) {
nsMap.put(prefix,
new XPathNamespace(context, prefix,
current.getNamespaceURI(prefix)));
}
}
ParentNode parent = current.getParent();
current = (parent instanceof Element)? (Element)parent: null;
}
nsMap.put("xml", new XPathNamespace(context,
"xml", "http://www.w3.org/XML/1998/namespace"));
return nsMap.values().iterator();
}
public Iterator getParentAxisIterator(Object contextNode) {
Object parent = null;
if (contextNode instanceof Node) {
parent = ((Node)contextNode).getParent();
}
else if (contextNode instanceof XPathNamespace) {
parent = ((XPathNamespace)contextNode).getElement();
}
if (parent != null) {
return new SingleObjectIterator(parent);
}
return null;
}
public Iterator getAttributeAxisIterator(Object contextNode) {
if (contextNode instanceof Element) {
Element e = (Element)contextNode;
int max = e.getAttributeCount();
List attrs = new ArrayList(max);
for (int i=0; i<max; i++) {
attrs.add(e.getAttribute(i));
}
return attrs.iterator();
}
return null;
}
/**
* Returns a parsed form of the given xpath string, which will
* be suitable for queries on XOM documents.
*/
public XPath parseXPath(String xpath) throws SAXPathException {
return new XOMXPath(xpath);
}
public Object getDocumentNode(Object contextNode) {
if (contextNode instanceof Node) {
return ((Node)contextNode).getDocument();
}
return null;
}
public String getElementQName(Object obj) {
return ((Element)obj).getQualifiedName();
}
public String getAttributeQName(Object obj) {
return ((Attribute)obj).getQualifiedName();
}
public String getNamespaceStringValue(Object obj) {
return ((XPathNamespace)obj).getURI();
}
public String getNamespacePrefix(Object obj) {
return ((XPathNamespace)obj).getPrefix();
}
public String getTextStringValue(Object obj) {
if (obj instanceof Text) {
return ((Text)obj).getValue();
}
return "";
}
public String getAttributeStringValue(Object obj) {
return ((Attribute)obj).getValue();
}
public String getElementStringValue(Object obj) {
return ((Element)obj).getValue();
}
public String getProcessingInstructionTarget(Object obj) {
return ((ProcessingInstruction)obj).getTarget();
}
public String getProcessingInstructionData(Object obj) {
return ((ProcessingInstruction)obj).getValue();
}
public String getCommentStringValue(Object obj) {
return ((Comment)obj).getValue();
}
public String translateNamespacePrefixToUri(String prefix, Object context)
{
Element element = null;
if (context instanceof Element) {
element = (Element)context;
}
else if (context instanceof Node) {
Node parent = ((Node)context).getParent();
if (parent instanceof Element) {
element = (Element)context;
}
}
else if (context instanceof XPathNamespace) {
element = ((XPathNamespace)context).getElement();
}
if ( element != null ) {
String uri = element.getNamespaceURI(prefix);
if (uri.length() != 0) {
return uri;
}
}
return null;
}
public Object getDocument(String url) throws FunctionCallException {
try {
return new Builder().build(url);
}
catch (Exception e) {
throw new FunctionCallException(e.getMessage());
}
}
private static class XPathNamespace {
/** * The XOM element to which the namespace is attached. */
private Element element;
/** * The namespace prefix. */
private String prefix;
/** * The namespace URI. */
private String uri;
/**
* Creates a namespace-node wrapper for a namespace node
* assigned to the given element.
*/
public XPathNamespace(Element element, String prefix, String uri)
{
this.element = element;
this.prefix = prefix;
this.uri = uri;
}
/**
* Returns the element from which this namespace node has
* been retrieved. The result may be null when the namespace
* node has not yet been assigned to an element.
*
* @return the element from which this namespace node has
* been retrieved.
*/
public Element getElement()
{
return this.element;
}
/**
* Returns the namespace prefix of this namespace node.
*
* @return the namespace prefix of this namespace node.
*/
public String getPrefix()
{
return this.prefix;
}
/**
* Returns the namespace URI of this namespace node.
*
* @return the namespace URI of this namespace node.
*/
public String getURI()
{
return this.uri;
}
public String toString()
{
return ("[xmlns:" + this.getPrefix() + "=\"" +
this.getURI() + "\", element=" +
this.getElement().getLocalName() + "]" );
}
}
}
- Patched DocumentNavigator (was [XOM-interest] XPath support for XOM), Laurent Bihanic, 02/07/2003
Archive powered by MHonArc 2.6.24.