Skip to Content.
Sympa Menu

xom-interest - Re: [XOM-interest] XOM and XPath

xom-interest AT lists.ibiblio.org

Subject: XOM API for Processing XML with Java

List archive

Chronological Thread  
  • From: Wolfgang Hoschek <whoschek AT lbl.gov>
  • To: Robert Stagner <restagner AT earthlink.net>
  • Cc: xom-interest AT lists.ibiblio.org
  • Subject: Re: [XOM-interest] XOM and XPath
  • Date: Thu, 12 Feb 2004 11:14:14 -0800

As a "newbie" to XOM and a relative novice to XML, in general,
please forgive my ignorance if my question seems a bit off topic. But, after reviewing the XOM documentation and reading a bit of the XOM API, I was wondering if anyone knows if it's possible to use XPath within XOM? Are there any methods within XOM that can leverage XPath's functionality? Any sort of examples would be of great help.



Not currently. Jaxen works with at least some versions of XOM, though I don't know if it's up to date. There's not yet any official XPath support in XOM.

For the moment, I'm using the Jaxen XOM code someone else posted in an ad hoc way to this list some months ago, which works with d24 and any version since I started using it with xom-1.0d19. (attached below). There is another kind of Jaxen XOM code in the Jaxen CVS repository which I have not tried, but that probably also works fine.

Wolfgang.
/*
*/

package nu.xom.xpath.jaxen;


import nu.xom.Attribute;
import nu.xom.Builder;
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 org.jaxen.DefaultNavigator;
import org.jaxen.FunctionCallException;
import org.jaxen.XPath;
import org.jaxen.util.SingleObjectIterator;
import org.saxpath.SAXPathException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
* 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() + "]" );
}
}
}/*
*/


package nu.xom.xpath.jaxen;

import org.jaxen.BaseXPath;
import org.jaxen.JaxenException;


/**
* 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());
}
}


Archive powered by MHonArc 2.6.24.

Top of Page