xom-interest AT lists.ibiblio.org
Subject: XOM API for Processing XML with Java
List archive
- From: Laurent Bihanic <laurent.bihanic AT atosorigin.com>
- To: XOM-interest <XOM-interest AT lists.ibiblio.org>
- Subject: [XOM-interest] XPath support for XOM
- Date: Thu, 30 Jan 2003 16:16:20 +0100
[Same mail but with the source code attached!]
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 org.jaxen.JaxenException; import org.jaxen.BaseXPath; import org.jaxen.Navigator; import org.jaxen.XPath; /** * An XPath implementation for the XOM model * <p> * This is the main entry point for matching an XPath against a XOM * tree. You create a compiled XPath object, then match it against * one or more context nodes using the {@link #selectNodes} * method, as in the following example:</p> * <pre> * Object xomNode = ...; // Document, Element, etc. * XPath path = new XOMXPath("a/b/c"); * List results = path.selectNodes(xomNode); * </pre> * * @see <a href="http://jaxen.sourceforge.net/">The Jaxen project</a> */ public class XOMXPath extends BaseXPath { /** * Constructs given an XPath expression string. * * @param xpathExpr The XPath expression. * * @throws JaxenException if there is a syntax error while * parsing the expression. */ public XOMXPath(String xpathExpr) throws JaxenException { super(xpathExpr, DocumentNavigator.getInstance()); } }
/* */ 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 uri; String prefix; 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, uri)); } } 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 JDOM 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() + "]" ); } } }
-
[XOM-interest] XPath support for XOM,
Laurent Bihanic, 01/30/2003
- Re: [XOM-interest] XPath support for XOM, Elliotte Rusty Harold, 01/30/2003
- <Possible follow-up(s)>
- [XOM-interest] XPath support for XOM, Laurent Bihanic, 01/30/2003
Archive powered by MHonArc 2.6.24.