2012-01-30 4 views
1

Я пытаюсь разобрать элемент dom.Анализ xml с использованием Java

Элемент Элемент:

<?xml version="1.0" encoding="UTF-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom"> 
    <id>http://X/feed2</id> 
    <title>Sample Feed</title> 
    <entry> 
    <id>http://X/feed2/104</id> 
    <title>New Title</title> 
    </entry> 
</feed> 

Я пытаюсь извлечь следующую запись:

<entry> 
    <id>http://top.cs.vt.edu/libx2/[email protected]/feed2/104</id> 
    <title>New Title</title> 
</entry> 

Я разбора XML с помощью XPath:

«/ атом: подача/atom: entry [atom: id = \ "http: // X/feed2/104 \"] "

Но я получаю исключение, когда пытаюсь разобрать Dom Элемент. Может ли кто-нибудь предложить простой подход для достижения этого на Java?

Пожалуйста, смотрите мой полный код:

public static parseXml() { 
     String externalEntryIdUrl = "http://theta.cs.vt.edu/~rupen/thirtylibapps/137"; 
     String externalFeedUrl = StringUtils.substringBeforeLast(externalEntryIdUrl, "/"); 
     try { 
      URL url = new URL(externalFeedUrl); 
      InputStream externalXml = new BufferedInputStream(url.openStream()); 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      Document doc = db.parse(externalXml); 
      Element externalFeed = doc.getDocumentElement(); 
      String atomNameSpace = "xmlns:atom=\"http://www.w3.org/2005/Atom\""; 
      String entryIdPath = String.format("//%s:entry[%s:id=%s]", atomNameSpace, atomNameSpace, externalEntryIdUrl); 
      Element externalEntry = (Element) XPathSupport.evalNode(entryIdPath, externalFeed); 
     } catch (Exception ex) { 
      // Throw exception 
     } 
    } 

static synchronized Node evalNode(String xpathExpr, Node node) { 
    NodeList result = evalNodeSet(xpathExpr, node); 
    if (result.getLength() > 1) 
     throw new Error ("More than one node for:" + xpathExpr); 
    else if (result.getLength() == 1) 
     return result.item(0); 
    else 
     return null; 
} 

static synchronized NodeList evalNodeSet(String xpathExpr, Node node) { 
     try { 
       static XPath xpath = factory.newXPath(); 
       xpath.setNamespaceContext(context); 

       static NamespaceContext context = new NamespaceContext() { 
        private Map<String, String> prefix2URI = new HashMap<String, String>(); 
        { 
         prefix2URI.put("libx", "http://libx.org/xml/libx2"); 
         prefix2URI.put("atom", "http://www.w3.org/2005/Atom"); 
        } 
       }; 

      XPathExpression expr = xpath.compile(xpathExpr); 
      Object result = expr.evaluate(node, XPathConstants.NODESET); 
      return (NodeList)result; 
     } catch (XPathExpressionException xpee) { 
      throw new Error ("An xpath expression exception: " + xpee); 
     } 
    } 

СЕРЬЕЗНОМУ: >> java.lang.Error: Исключение выражение XPath: javax.xml.xpath.XPathExpressionException

+1

* «Я получаю исключение» * Это «TooManyKittensException»? Desess the tom cat. Что-то другое? Возможно, вы можете поделиться им (то есть скопировать/вставить) с нами. –

+1

Вы связали (зарегистрировали пространство имен) в своем Java-коде префикс 'atom' в пространство имен' 'http://www.w3.org/2005/Atom?'? Вы должны сделать это (рекомендуется) или использовать что-то вроде: '/ */* [local-name() = 'entry'] [* [local-name() = 'id'] = 'http: // X/feed2/104] '' –

ответ

0

Я полагал, что я не установил осведомленность об пространстве имен при извлечении xml из URL-адреса.

Так,

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 

Это исправляет мою проблему. Не делая этого, установка контекста пространства имен для экземпляра XPathFactory при анализе xml, как показано в моем примере, не работает сама по себе.

0

Вы могли бы использовать в NamespaceContext и сделать что-то вроде следующего:

package forum9059851; 

import java.io.FileInputStream; 
import java.util.Iterator; 
import javax.xml.namespace.NamespaceContext; 
import javax.xml.xpath.*; 
import org.w3c.dom.Element; 
import org.xml.sax.InputSource; 

public class Demo { 

    public static void main(String[] args) { 
     try { 
      XPathFactory xpf = XPathFactory.newInstance(); 
      XPath xp = xpf.newXPath(); 
      xp.setNamespaceContext(new MyNamespaceContext()); 
      XPathExpression xpe = xp.compile("ns:feed/ns:entry"); 
      FileInputStream xmlStream = new FileInputStream("src/forum9059851/input.xml"); 
      InputSource xmlInput = new InputSource(xmlStream); 
      Element result = (Element) xpe.evaluate(xmlInput, XPathConstants.NODE); 
      System.out.println(result); 
     } catch (Exception ex) { 
      // Throw exception 
     } 
    } 

    private static class MyNamespaceContext implements NamespaceContext { 

     public String getNamespaceURI(String prefix) { 
      if("ns".equals(prefix)) { 
       return "http://www.w3.org/2005/Atom"; 
      } 
      return null; 
     } 

     public String getPrefix(String namespaceURI) { 
      return null; 
     } 

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

    } 

} 
0

Если вы не хотите изобретать велосипед и хотите, чтобы разобрать данные корма, я бы рекомендуем обратиться к уже имеющейся библиотеке Rome.

Смежные вопросы