自定义Java 5 的新XPath API 函数

Java 5 的XPath API已经非常好用了,它实现了XPath1.0标准,功能已经比较强大了。

但是,还可以对它进行扩展,自定义XPath API 函数。例如,想要支持matches函数,以便匹配正则表达式,就可如下:

  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  
  xpath.setXPathFunctionResolver(new MatchesFunctionContext());
  xpath.setNamespaceContext(new MyNamespaceContext());

  
  XPathExpression expr = xpath.compile("//*[ext:matches(@href,\"/photos/.*/[0-9]+/\")]/IMG");

  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  
  NodeList nodes;

  nodes = (NodeList) result;// XPathAPI.selectNodeList(doc, "//*[@id=\"Main\"]");
  System.out.println(nodes.getLength());
  for (int i = 0; i < nodes.getLength(); i++) {
//   System.out.println(nodes.item(i).getNodeName());
//   System.out.println(nodes.item(i).getTextContent());

   
  }

 

import javax.xml.namespace.QName;
import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionResolver;

public class MatchesFunctionContext implements XPathFunctionResolver{
   private static final QName name
    = new QName("http://ext.com", "matches");

   public XPathFunction resolveFunction(QName name, int arity) {

       if (name.equals(MatchesFunctionContext.name) ) {
           return new FuncMatches();
       }
       return null;
   }

}

import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;

public class MyNamespaceContext implements NamespaceContext
{
    public String getNamespaceURI(String prefix)
    {
        if (prefix == null)
          throw new IllegalArgumentException("The prefix cannot be null.");
       
        if (prefix.equals("ext"))
            return "http://ext.com";
        else
            return null;
    }
   
    public String getPrefix(String namespace)
    {
        if (namespace == null)
          throw new IllegalArgumentException("The namespace uri cannot be null.");
        if (namespace.equals("http://ext.com"))
          return "ext";
        else
          return null;
    }

    public Iterator getPrefixes(String namespace)
    {
        return null;
    }

}

 


import java.util.List;

import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Execute the Contains() function.
 *
 * @xsl.usage advanced
 */
public class FuncMatches implements XPathFunction {
 static final long serialVersionUID = 5084753781887919723L;

 /**
  *
  */
 public Object evaluate(List args) throws XPathFunctionException {

  if (args.size() != 2) {
   throw new XPathFunctionException(
     "Wrong number of arguments to valid-isbn()");
  }
  Object o = args.get(0);
  String s1 = null;
  if (o instanceof NodeList) {

   NodeList list = (NodeList) o;
   if (list.getLength() == 0) {
    return Boolean.FALSE;
   }

   Node node = list.item(0);
   // getTextContent is available in Java 5 and DOM 3.
   // In Java 1.4 and DOM 2, you'd need to recursively
   // accumulate the content.
   s1 = node.getTextContent();
  }

  String s2 = (String) args.get(1);

  // Add this check for JDK consistency for empty strings.
  if (s1.length() == 0 && s2.length() == 0)
   return Boolean.TRUE;

  boolean match = s1.matches(s2);
  return (match) ? Boolean.TRUE : Boolean.FALSE;
 }

}

你可能感兴趣的:(java,xml)