![]() |
|
|
|
#1 |
|
Hi there,
I'm using, for the first time, the JDK1.5 Xpath API. I need to find elements in a Hibernate-generated .hbm.xml file. These files come with a <!DOCTYPE header mentioning a remote URL. The Xpath parser fetches the URL from the hibernate.sourceforge site. So far so good. However, if I unplug the network, I get (after a *long* timeout) a java.net.SocketException. I looked around and I found out that I have to define a class implementing EntityResolver to change the default behaviour (i.e., fetch the DTD over the net) and obtain an InputSource from it. Something along the lines of: public class UriTransform implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) { return new InputSource(new StringReader("")); } } Now my problem is: How do I do it? Neither in javax.xml.xpath.XPath nor in javax.xml.xpath.XPathFactory did I find an appropriate place nor did I find a method to gain access to the underlying SAX parser. Here's my code: XPath xpath = XPathFactory.newInstance().newXPath(); final String expression = "//property"; final String completePath = ... //file path InputSource inputSource = new InputSource(completePath); DTMNodeList nodes = (DTMNodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET); Any ideas? TIA andy abcd_68@yahoo.co.uk |
|
|
|
|
#2 |
|
Posts: n/a
|
wrote: > However, if I unplug the network, I get (after a *long* timeout) a > java.net.SocketException. I looked around and I found out that I have > to define a class implementing EntityResolver to change the default > behaviour (i.e., fetch the DTD over the net) and obtain an InputSource > from it. > Now my problem is: How do I do it? Neither in javax.xml.xpath.XPath nor > in javax.xml.xpath.XPathFactory did I find an appropriate place nor did > I find a method to gain access to the underlying SAX parser. I don't know how to do it if you pass an InputSource to the evaluate method. You can however also pass in an object where the object is a W3C DOM Node. And if you look at DocumentBuilder it has a method setEntityResolver. That should allow you to create a DOM Document without fetching the DTD from the remote host, and you can then pass in the Document to the evaluate method. I am not sure a DOM Node/Document is the most efficient data structure to do XPath on but at least that approach might work for your problem. -- Martin Honnen http://JavaScript.FAQTs.com/ |
|
|
|
#3 |
|
Posts: n/a
|
One way around this is to instantiate the parser yourself, configure it
appropriately, then pass it to the transformer wrapped in a SAXSource. (There ought to be a way to pass an entity resolver/URI resolver through the XPath APIs, but I'm having trouble finding it.) |
|
|
|
#4 |
|
Posts: n/a
|
Martin Honnen wrote:
> You can however also pass in an object where the object is a W3C > DOM Node. Thank you so much Martin, that actually fixed my problem! The following code now works with and without a network connection: --------------------------------- DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBu ilder(); db.setEntityResolver(new UriTransform()); final String completePath = //file path Document doc = db.parse(new File(completePath)); XPath xpath = XPathFactory.newInstance().newXPath(); final String expression = "//property"; DTMNodeList nodes = (DTMNodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET); --------------------------------- |
|